Thread: Dynamic loading with C++

  1. #1
    Registered User
    Join Date
    Jan 2006
    Location
    Europe/Belgrade
    Posts
    78

    Dynamic loading with C++

    I have problem with dynamic loading function with C++ (in C it works).
    Let test.cpp be
    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    void f(string s)
    {
      cout << s << endl;
    }
    and main.cpp
    Code:
    #include <dlfcn.h>
    #include <string>
    
    using namespace std;
    
    extern "C" void f(string);
     
    int main()
    {
      void* handle = dlopen("libtest.so", RTLD_LAZY);
      void (*test)(string) = dlsym(handle, "f");
      (*test)("Hello, World!");
      dlclose(handle); 
    }
    Then, I made libtest.so with
    Code:
    g++ -c test.c
    g++ -shared -fPIC -o libtest.so test.o
    put it into /usr/lib and set appropriate file attributes. But,
    Code:
    g++ -ldl main.cpp
    gives error main.cpp:12: error: invalid conversion from `void*' to `void (*)(std::string)'.
    Why? Same thing works in C with char* and printf() instead of string and cout.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    have you tried to cast the pointer returned by the dlsym function to the proper type of the pointer?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Jan 2006
    Location
    Europe/Belgrade
    Posts
    78
    If I cast it with
    Code:
    void (*test)(string) = (void (*)(string))dlsym(handle, "f");
    then it compiles but on run gives Segmentation fault.

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Trouble is the namemangling.
    have a look in the library how the function is actually called. ( use nm ).
    Guess there should be a better way.
    Got this to run:
    the lib
    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    void testfunc(string s)
    {
      cout << s << endl;
    }
    Code:
    #include <dlfcn.h>
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    typedef void (*test)(string);
     
    int main()
    {
      void* handle = dlopen("libtest.so", RTLD_LAZY);
      if ( 0 == handle ) {
          cout << "failed to load 'libtest.so'." << endl;
          exit(1);
      }
    
      test t = (test)dlsym(handle, "_Z8testfuncSs");
      if ( 0 == t ) {
          cout << "failed to load 'testfunc()'." << endl;
          exit(1);
      }
      t("Hello, World!");
      dlclose(handle); 
    }
    Kurt
    Last edited by ZuK; 12-24-2006 at 05:45 AM.

  5. #5
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    After some experimenting I think the easiest way is to declare the exported function in the dynamic libarary as extern "C", and use it as extern "C" as well. This way there are no namemangling issues.
    Kurt

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    There is still one other issue: dlsym() returns a void*, and conversions between object- and function-pointers are absolutely invalid in C++. (GCC allows them, but it will issue a warning on most levels.)

    See here:
    http://www.trilithium.com/johan/2004...em-with-dlsym/
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    To prevent SegFault - just check the returned pointer before use
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #8
    Registered User
    Join Date
    Jan 2006
    Location
    Europe/Belgrade
    Posts
    78
    extern declaration must be placed into f's definition in the test.cpp and removed from main.cpp.
    Thanks for the help, especially for the URL about pointer conversions.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Loading data into a dynamic array
    By serge in forum C++ Programming
    Replies: 9
    Last Post: 06-18-2009, 03:36 PM
  2. Cargo loading system
    By kyle rull in forum C Programming
    Replies: 1
    Last Post: 04-20-2009, 12:16 PM
  3. Loading a file of words into dynamic char**
    By strakerc in forum C Programming
    Replies: 11
    Last Post: 07-11-2008, 07:20 PM
  4. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM
  5. Win32 API - Dynamic Link Library Loading - behind the scenes
    By Unregistered in forum Windows Programming
    Replies: 2
    Last Post: 04-05-2002, 08:31 AM