0

I used the c library(nats.c) in a c++ project,I have done the following work so far(part of the code):

extern "C" {
#include "nats/nats.h"
}

#include "iostream"

class Connection {
 public:
  void Test() {
     natsConnection_ConnectTo(&natsConnection_, "nats://localhost:4222");

     natsConnection_PublishString(natsConnection_, "foo", "hello world");

     natsConnection_Subscribe(&natsSubscription_, natsConnection_, "foo",
      [](natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *closure) {
        std::cout << "received:" << natsMsg_GetSubject(msg) << ","
                  << natsMsg_GetDataLength(msg) << "," << natsMsg_GetData(msg);
        natsMsg_Destroy(msg);
      },
      NULL);
  }
}

But I found an error occurred during compilation:

[  1%] Building CXX object CMakeFiles/glink.dir/src/transport/nats/connection.cc.o
[  5%] Built target glink
[  6%] Linking CXX executable bin/main
CMakeFiles/glink.dir/src/transport/nats/connection.cc.o: In function `glink::nats::Connection::Test()::{lambda(__natsConnection*, __natsSubscription*, __natsMsg*, void*)#1}::_FUN(__natsConnection*, __natsSubscription*, __natsMsg*, void*)':
connection.cc:(.text+0x2f): undefined reference to `natsMsg_GetSubject'
connection.cc:(.text+0x6f): undefined reference to `natsMsg_GetDataLength'
connection.cc:(.text+0x98): undefined reference to `natsMsg_GetData'
CMakeFiles/glink.dir/src/transport/nats/connection.cc.o: In function `glink::nats::Connection::Test()':
connection.cc:(.text+0x12e): undefined reference to `natsConnection_ConnectTo'
connection.cc:(.text+0x141): undefined reference to `natsConnection_PublishString'
CMakeFiles/glink.dir/src/transport/nats/connection.cc.o: In function `glink::nats::Connection::Test()::{lambda(__natsConnection*, __natsSubscription*, __natsMsg*, void*)#1}::_FUN(__natsConnection*, __natsSubscription*, __natsMsg*, void*)':
connection.cc:(.text+0xc2): undefined reference to `natsMsg_Destroy'
connection.cc:(.text+0x116): undefined reference to `natsMsg_Destroy'
CMakeFiles/glink.dir/src/transport/nats/connection.cc.o: In function `glink::nats::Connection::Test()':
connection.cc:(.text+0x15f): undefined reference to `natsConnection_Subscribe'
collect2: error: ld returned 1 exit status
gmake[2]: *** [bin/main] Error 1
gmake[1]: *** [CMakeFiles/main.dir/all] Error 2
gmake: *** [all] Error 2
The terminal process terminated with exit code: 2

I use cmake to build project, The code is as follows(part of the code):

set(LINK_DIR /usr/local/lib64)
link_directories(${LINK_DIR})

add_library(${LIBRARY_NAME} OBJECT ${PROJECT_SOURCES})

target_include_directories(${LIBRARY_NAME} PUBLIC ${PROJECT_SOURCE_DIR})
target_include_directories(${LIBRARY_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include)

add_executable(main app/main.cc)

target_link_libraries(main PRIVATE ${LIBRARY_NAME} ${CONAN_LIBS} libnats.so)

The corresponding path information is listed in the shell:

$ pwd
/usr/local/lib64

$ ls -l | grep nats
lrwxrwxrwx 1 root root       14 Jun  8 09:38 libnats.so -> libnats.so.2.1
lrwxrwxrwx 1 root root       16 Jun  8 09:38 libnats.so.2.1 -> libnats.so.2.1.0
-rwxr-xr-x 1 root root   292624 Jun  8 09:33 libnats.so.2.1.0
-rw-r--r-- 1 root root   449072 Jun  8 09:33 libnats_static.a

What did i do wrong?


I found that I wrote the wrong cmake file, Now adjust as follows:

FIND_PATH(
    NATS_C_INCLUDE_DIR nats/nats.h
    HINTS ${NATS_C_DIR}
)

FIND_LIBRARY(NATS_C_LIBRARY
    NAMES libnats.so libnats.a libnats.lib libnats.dll
    HINTS ${NATS_C_DIR}
)

FIND_PACKAGE_HANDLE_STANDARD_ARGS(libnats DEFAULT_MSG
    NATS_C_INCLUDE_DIR
    NATS_C_LIBRARY
)

SET(NATS_C_INCLUDE_DIRS ${NATS_C_INCLUDE_DIR})
SET(NATS_C_LIBRARIES ${NATS_C_LIBRARY})
add_library(${LIBRARY_NAME} OBJECT ${PROJECT_SOURCES})

target_link_libraries(${LIBRARY_NAME} PRIVATE ${CONAN_LIBS} ${NATS_C_LIBRARIES})

target_include_directories(${LIBRARY_NAME} PUBLIC ${PROJECT_SOURCE_DIR})
target_include_directories(${LIBRARY_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_include_directories(${LIBRARY_NAME} PRIVATE ${NATS_C_INCLUDE_DIRS})

add_executable(main app/main.cc)
target_link_libraries(main PRIVATE ${LIBRARY_NAME})

Now it can be compiled, but the runtime prompts:

$ error while loading shared libraries: libnats.so.2.1: cannot open shared object file: No such file or directory

I have configured in ld.so.conf:

/usr/local/lib64
candycat
  • 435
  • 4
  • 13
  • These are undefined references which mean the problem may have to do with how you're compiling the program. – David G Jun 09 '20 at 03:15
  • This is an `extern "C"` issue. Basically, compiler thinks those functions are defined as C++ , not C: https://stackoverflow.com/questions/1041866/what-is-the-effect-of-extern-c-in-c – oakad Jun 09 '20 at 03:44
  • 1
    use `-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON` to print the compile/link commands. See whether your libnats is linked correctly. – halfelf Jun 09 '20 at 04:46
  • It looks like the linker is just not finding the object code. You could look at the symbols defined in libnats.so with the `nm` utility and see if the functions seem to be there. – Dennis Sparrow Jun 09 '20 at 04:47

0 Answers0