简体   繁体   中英

C++ Boost Library Undefined Reference On shm_open: DSO Missing From Command Line

I am writing an application which is to play the role of a subscriber in a DDS system. This subscriber will, upon receipt of data, write the value(s) to a shared memory location so that they can be read by another GUI application.

I have written a version of the application which compiles and runs A-OK on Windows, but I am now faced with creating a version to be run on Ubuntu. Being Windows native, this has proved to be troublesome for me.

To create the Ubuntu version, I have ported my codebase to a Ubuntu VM, and am now trying to compile it there, which is where I'm running into issues.

For the most part, everything compiles fine and the process is wonderfully similar to that on Windows. Unfortunately, the final statement to link all of my generated .o files is what fails. A bit of a description is below:

I'm using the boost interprocess library to write a header file that will provide the shared memory read/write operations. The .cpp which achieves this is as below: MemWriterH.cpp

#define BOOST_DATE_TIME_NO_LIB
#define CPP

#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <stdio.h>
#include <MemWriterH.h>

using namespace boost::interprocess;

extern "C" int writeToSharedMemory(char *data)
{
    //Remove shared memory on construction and destruction
    struct shm_remove
    {
        shm_remove()
        {
            //shared_memory_object::remove("MySharedMemory");
        }
        ~shm_remove()
        {
            //shared_memory_object::remove("MySharedMemory");
        }
    }remover;

    //Create a shared memory object.
    shared_memory_object shm(open_or_create, "MySharedMemory", read_write);
    //Set size
    shm.truncate(1000);

    //Map the whole shared memory in this process
    mapped_region region(shm, read_write);

    //Write given data to the mapped region
    //std::memset(region.get_address(), 'h', region.get_size());
    std::memcpy(region.get_address(), data, region.get_size());

    return 0;
}

extern "C" void readFromSharedMemeory(char toWriteIn[])
{
    //Open already created shared memory object.
    shared_memory_object shm(open_only, "MySharedMemory", read_only);

    //Map the whole shared memory in this process
    mapped_region region(shm, read_only);

    //Read data from shared memory into parameter
    //char *mem = static_cast<char*>(region.get_address());

    std::memcpy(toWriteIn, region.get_address(), region.get_size());
    printf("Read data OK");
    printf("\n%s", toWriteIn);
}

And its accompanying header: MemWriterH.h

#ifdef CPP
    extern "C" int writeToSharedMemory(char *);
    extern "C" void readFromSharedMemeory(char *);
#else
    int writeToSharedMemory( char *);
    void readFromSharedMemeory(char* toWriteIn);
#endif

These are then compiled to a .o file using:

g++ -c -I/$HOME/workspace_c/HID_LDM_DDS/HID_LDM_DDS_INCLUDES/MEM_MAPPING/ *.cpp

Inside the application's main file, I have a #include which allows the functions above to be used.

While there are various other elements to this application (as seen below), these all seem to compile, build, and link fine.

This resulting MemWriterH.o file is then used in a final GCC statement which — I believe — links all the .o files together to produce the application's executable. This final statement is:

gcc HID_LDM_DDS_SUB.o $HOME/workspace_c/HID_LDM_DDS/HID_LDM_DDS_HELPER/HID_LDM_DDS_HELPER.o $HOME/workspace_c/HID_LDM_DDS/HID_LDM_DDS_INCLUDES/CheckStatus.o $HOME/workspace_c/HID_LDM_DDS/HID_LDM_DDS_INCLUDES/MEM_MAPPING/MemWriterH.o $HOME/workspace_c/HID_LDM_DDS/HID_LDM_DDS_IDL/LDMSacDcps.o $HOME/workspace_c/HID_LDM_DDS/HID_LDM_DDS_IDL/LDMSplDcps.o $OSPL_HOME/lib/libddskernel.so $OSPL_HOME/lib/libdcpssac.so

which, unfortunately, gives me the error:

/usr/bin/ld: /home/bob/workspace_c/HID_LDM_DDS/HID_LDM_DDS_INCLUDES/MEM_MAPPING/MemWriterH.o: undefined reference to symbol 'shm_open@@GLIBC_2.2'

/lib/i386-linux-gnu/librt.so.1: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status

At which point, I feel completely lost. The .cpp compiles to a .o without complaint, so I'm not quite sure where else to go from here. What is a DSO, and how do I add it to the command line?

EDIT:

An update now the problem's solved. As Sehe pointed out below, the library in which shm_open is defined was missing. This is included with the -lrt flag, which should be included after the .o files being linked ( see here for more explanation on that ).

Solving this did, however, lead to another issue whereby the compiler was complaining at several occurrences of an error along the lines of: 'undefined reference to std::some_function'. This, it turns out, was owing to an issue in linking C and C++ code (the header) using the gcc command. Adding a -lstdc++ flag, or using the g++ compile command ( see the answer here for a description of what's going on ) solves this, too, and all compiles successfully.

您应该完全按照消息提示添加丢失的库:链接器选项末尾的-lrt应该足够

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM