Undefined reference to DDSDomainParticipantFactory::get_instance

4 posts / 0 new
Last post
Offline
Last seen: 5 months 3 weeks ago
Joined: 05/13/2023
Posts: 12
Undefined reference to DDSDomainParticipantFactory::get_instance

Hello, I am experimenting with some C++ code using Connext on Ubuntu.  I've tried to cobble together some steps from the doc and examples to set up, compile, and build a simple application.  But I'm running into trouble as follows.

Below is a snippet of code I'm trying to run, simply instantiating a DomainParticipant object.  I've put together a build script which I believe sets up the environment correctly and invokes all the proper gcc options.

However, I'm getting a couple of "undefined reference" errors for DDSTheParticipantFactory->create_participant and DDS_PARTICIPANT_QOS_DEFAULT.

Am I missing the proper library to link into the build?  Please note that I've added almost *all* of the .so files from the /lib/x64Linux4gcc7.3.0 folder, thinking the definition must be in one of those.  But no such luck.

What am I missing to resolve these basic references?

Thanks for any help or insight!  I've made it a long way on my own but I'm sure I'm about to learn a *ton* from your answers. 

*** For the code (lifted from examples):

DDSDomainParticipant *participant =
DDSTheParticipantFactory->create_participant(
domain_id,
DDS_PARTICIPANT_QOS_DEFAULT,
NULL /* listener */,
DDS_STATUS_MASK_NONE);
 
*** And the build script (boiled down from the example build scripts) (linked libraries from x64Linux4gcc7.3.0 folder in green):

export NDDSHOME=/home/xenon/rti_connext_dds-6.1.2
export CONNEXTDDS_DIR=/home/xenon/rti_connext_dds-6.1.2
export CONNEXTDDS_ARCH=x64Linux4gcc7.3.0
export PATH="$NDDSHOME/bin":$PATH
export RTI_LD_LIBRARY_PATH="$NDDSHOME/lib/x64Linux4gcc7.3.0"
export LD_LIBRARY_PATH=$RTI_LD_LIBRARY_PATH:$LD_LIBRARY_PATH
gcc -I/home/xenon/rti_connext_dds-6.1.2/include/ -I/home/xenon/rti_connext_dds-6.1.2/include/ndds -D RTI_LINUX -D RTI_UNIX -DRTI_64BIT -L/home/xenon/rti_connext_dds-6.1.2/lib/x64Linux4gcc7.3.0 -lnddscpp -lnddsc -lnddscore -lrticonnextmsgcpp -lrticonnextmsgc -lrtiddsconnectorlua -llua -lnddscpp2 -lnddsmetp -lnddstransporttcp -lrtiapputilsc -lrticonnextmsgc -lrticonnextmsgcpp2 -lrtidlc -lrtidlcpp -lrtijniroutingservice -lrtimonitoring -lrtiroutingservice -lrtirsinfrastructure -o ESCSHMIService main.cpp FSM.cpp Log.cpp OPCUAServer.cpp open62541.c WorkingData.cpp tinyxml2.cpp -lstdc++
echo Build complete

*** I'm getting the following output (errors in red):
 
/usr/bin/ld: /tmp/cc7wLmzM.o: warning: relocation against `DDS_PARTICIPANT_QOS_DEFAULT' in read-only section `.text'
/usr/bin/ld: /tmp/cc7wLmzM.o: in function `cFSM::FSM_Cycle(eFSMState, eEvent)':
FSM.cpp:(.text+0x2a9): undefined reference to `DDSDomainParticipantFactory::get_instance()'
/usr/bin/ld: FSM.cpp:(.text+0x2d2): undefined reference to `DDS_PARTICIPANT_QOS_DEFAULT'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
Build complete

 
 

 

Organization:
Offline
Last seen: 3 months 3 days ago
Joined: 04/23/2014
Posts: 57

Hi riceman0,

I think that the main issue is that you are using gcc instead of g++ for building a C++ application.

Also, I'd like to give you a few tips:

  • You can load the Connext environment by running the scripts under <Connext intallation folder>/resource/scripts/rtisetenv_<arch>. For example:
    • source <Connnext installation folder>/resource/scripts/rtisetenv_x64Linux4gcc7.3.0.bash
    • This will set up the needed environment variables for you (NDDSHOME, LD_LIBRARY_PATH, PATH...)
  • There is no need to link all the Connext libraries (-lnddscpp -lnddsc -lnddscore -lrticonnextmsgcpp -lrticonnextmsgc -lrtiddsconnectorlua -llua -lnddscpp2 -lnddsmetp -lnddstransporttcp -lrtiapputilsc -lrticonnextmsgc -lrticonnextmsgcpp2 -lrtidlc -lrtidlcpp -lrtijniroutingservice -lrtimonitoring -lrtiroutingservice -lrtirsinfrastructure)
  • You can generate a simple example that contains a makefile (for reference) by running: rtiddsgen -language C++ -example x64Linux4gcc7.3.0 <idl_file_name>.idl
  • You can use CMake for your project, here you can find an example: https://github.com/rticommunity/rticonnextdds-examples/tree/master/examples/connext_dds/build_systems/cmake
  • I've seen that you are using the classic C++ API of Connext, is that for any specific reasons? My recommendation is to use the Modern C++ API if possible.
    • Then, the library that you need to link is "-lnddscpp2" (instead of "-lnddscpp"), and the flag for rtiddsgen is "-language C++11"

Let me know if that works for you,

Angel.

Offline
Last seen: 5 months 3 weeks ago
Joined: 05/13/2023
Posts: 12

Thank you Angel.

So I switched to g++ (I was using gcc with the -lstdc++ switch, is that different?), and reduced my linked libraries down to lnddscpp, but I get the same error.

I don't think I can use the IDL approach, because I am setting up my types and topics at *runtime*, I can't define those in IDL. 

I am familiar with the bash scripts, I basically copied those commands over to my build script above (but swapped out with hardcoded values temporarily for clarity). So I think that is equivalent to running that bash script.  But I tried running with the bash script instead, and same results.

Thanks for the info about the libraries... that makes sense that the '2' libraries are for the modern API.  Unfortunately at this point we are stuck with the classic one, that should work, right?

I see that example for the make file, like I said we can't use that approach directly because we are not utilizing IDL.  But I did compare mine to those make files (under resources/cmake/Modules) to see if they were linking anything special, and I don't see it.

So, if I'm setting up all of the environmental variables correctly, using g++, reduced my linked library down to -lnddscpp, shouldn't I *not* be getting that error?  In which library are those two things (get_instance and DDS_PARTICIPANT_QOS_DEFAULT) defined?

Thanks for this help and any future answers!  Sorry my setup is a little different than the examples.

 

*** edit: actually a thing I could easily have missed were the proper #defines -- this is something that the code generation does for you that I may have missed.  Do I need something more than these?

-D RTI_LINUX -D RTI_UNIX -D RTI_64BIT

 

 

 

 

Offline
Last seen: 3 months 3 days ago
Joined: 04/23/2014
Posts: 57

Hi riceman0,

Ohh, I didn't see the -lstdc++.

I mentioned to run codegen with an IDL to have an example about how to build a Connext application, so you can add things on top of that. I attach here a generated example that contains the corresponding makefile for classic C++, so you can review it.

Sorry I didn't mention it before, but for a simple classic C++ application, you need at least 3 libraries, nddsc, nddscore, nddscpp (-lnddscpp -lnddsc -lnddscore). You may need other libraries depending on the features that you are using in your application.

About your questions:

  • The classic C++ API should work perfectly :)
  • DDSDomainParticipantFactory::get_instance and DDS_PARTICIPANT_QOS_DEFAULT are defined in libnddscpp 

If you continue having issues, I'd recommend you to contact your account team to review if there are other dependencies that might be missing for your specific application.

Hope this helps,

Angel.

File Attachments: