1

Now, I have been trying load dynamic library for an hour,stuck at unable to load symbol,Let me show you my problem. Here is the snippet of my code,

void *hInstLib = dlopen("libnbuVmwareTools.so",RTLD_NOW);
LoadOneFunc(hInstLib,(void **)&vmcGetDiskChangedInfoStrm_Ptr,"vmcGetDiskChangedInfoStrm");

void LoadOneFunc(void* dlHandle, void** pFunction, const char* funcName)

{

   std::stringstream strStream;

   *pFunction = dlsym(dlHandle, funcName);

   char* dlErrStr = dlerror();

   if (*pFunction == NULL || dlErrStr != NULL) 

    {

      strStream << "Failed to load " << funcName << ". Error = " << dlErrStr << "\n";

      throw std::runtime_error(strStream.str().c_str());

    }

}

Now, I have checked that vmcGetDiskChangedInfoStrm is present in libnbuVmwareTools.so,

And lib is loaded successfully, But,

[root@vm vmcbt]# g++ dltest.cpp -L/root/vmware/usr/openv/lib -lnbuVmwareTools
[root@vm vmcbt]# ./a.out 
Successfully loaded Library 
Error while dynamically loading : Failed to load vmcGetDiskChangedInfoStrm. Error = /root/vmware/usr/openv/lib/libnbuVmwareTools.so: undefined symbol: vmcGetDiskChangedInfoStrm

And when checked if symbol is present in .so file using nm -C command,

[root@vm vmcbt]# cd
[root@vm ~]# cd  /root/vmware/usr/openv/lib/
[root@vm lib]# nm -C libnbuVmwareTools.so | grep vmcGetDiskChangedInfoStrm.
00000000006680bc T vmcGetDiskChangedInfoStrm(void*, int, long, char const*, char const*, char const*, char const*, std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&, bool)

I am not getting this issue, Any help on this would be greatly appreciated.

rushikesh
  • 171
  • 1
  • 2
  • 14

1 Answers1

4

The function is defined as a C++ function (I can see that because it has argument types in the listing). So you need to figure out what the name is, probably _Z25vmcGetDiskChangedInfoStrmPvilPKcS1_S1_S1_RSt18basic_stringstreamIcSt11char_traitsIcESaIcEEb and then look for that.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • 1
    Run `nm` without the -C argument, and you'd find the proper name(though it's harder to figure out if the function is overloaded) – nos Sep 22 '14 at 07:20
  • or if possible, eschew C++ types in your function's signature in favour of C types and [`extern "C"`](http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c) it – Steve Lorimer Sep 22 '14 at 07:25
  • @Steve: Hard to pass in a `stringstream` type then... – Mats Petersson Sep 22 '14 at 07:34
  • You were correct ,I was able to find function name defined in .so file using only nm "without -C". but there are lots of these functions, I need to load from this linker lib. Is there any other way to use the earlier function name, as I am using header file provided to me.? – rushikesh Sep 22 '14 at 08:13
  • My guess is that you are not supposed to load them manually, but link with the shared library... – Mats Petersson Sep 22 '14 at 08:17
  • you mean to say link them at command line , at the time of compilation? Someone has pointed to another answer [redirected Q], where it is said to use extern C {void function()}, would it be helpful? – rushikesh Sep 22 '14 at 08:21
  • Yes, I mean link on the command-line. Are you actually planning for your product to run without this library (or have multiple variants/versions of libraries like this one)? If not, then just link with the library directly. – Mats Petersson Sep 22 '14 at 08:23
  • `extern "C"` is also mentioned above, but needs to be used on the library, not in your code - because the symbol published in the library is made by the compiler when the library is compiled, not when you try to use the symbol. – Mats Petersson Sep 22 '14 at 08:24
  • thanks, It is working on static linking. But I was hoping for dynamic loading as I am using another lib. with runtime RTLD_LAZY loading. – rushikesh Sep 22 '14 at 08:38