Sunday, June 10, 2012

C++ Dynamic Shared Library on Linux

This is a follow-up to this question .

I'm trying to create a shared class library in C++ on Linux. I'm able to get the library to compile, and I can call some of the (non-class) functions using the tutorials that I found here and here . My problems start when I try to use the classes that are defined in the library. The second tutorial that I linked to shows how to load the symbols for creating objects of the classes defined in the library, but stops short of using those objects to get any work done.

Does anyone know of a more complete tutorial for creating shared C++ class libraries that also shows how to use those classes in a separate executable? A very simple tutorial that shows object creation, use (simple getters and setters would be fine), and deletion would be fantastic. A link or a reference to some open source code that illustrates the use of a shared class library would be equally good.

Although the answers from codelogic and nimrodm do work, I just wanted to add that I picked up a copy of Beginning Linux Programming since asking this question, and its first chapter has example C code and good explanations for creating and using both static and shared libraries. These examples are available through Google Book Search in an older edition of that book .

Source: Tips4all


  1. myclass.h

    #ifndef __MYCLASS_H__
    #define __MYCLASS_H__

    class MyClass

    /* use virtual otherwise linker will try to perform static linkage */
    virtual void DoSomething();

    int x;


    #include "myclass.h"
    #include <iostream>

    using namespace std;

    extern "C" MyClass* create_object()
    return new MyClass;

    extern "C" void destroy_object( MyClass* object )
    delete object;

    x = 20;

    void MyClass::DoSomething()

    #include <dlfcn.h>
    #include <iostream>
    #include "myclass.h"

    using namespace std;

    int main(int argc, char **argv)
    /* on Linux, use "./" */
    void* handle = dlopen("", RTLD_LAZY);

    MyClass* (*create)();
    void (*destroy)(MyClass*);

    create = (MyClass* (*)())dlsym(handle, "create_object");
    destroy = (void (*)(MyClass*))dlsym(handle, "destroy_object");

    MyClass* myClass = (MyClass*)create();
    destroy( myClass );

    On Mac OS X, compile with:

    g++ -dynamiclib -flat_namespace -o
    g++ -o class_user

    On Linux, compile with:

    g++ -fPIC -shared -o
    g++ -ldl -o class_user

    If this were for a plugin system, you would use MyClass as a base class and define all the required functions virtual. The plugin author would then derive from MyClass, override the virtuals and implement create_object and destroy_object. Your main application would not need to be changed in any way.

  2. The following shows an example of a shared class library shared.[h,cpp] and a main.cpp module using the library. It's a very simple example and the makefile could be made much better. But it works and may help you:

    shared.h defines the class:

    class myclass {
    int myx;


    myclass() { myx=0; }
    void setx(int newx);
    int getx();

    shared.cpp defines the getx/setx functions:

    #include "shared.h"

    void myclass::setx(int newx) { myx = newx; }
    int myclass::getx() { return myx; }

    main.cpp uses the class,

    #include <iostream>
    #include "shared.h"

    using namespace std;

    int main(int argc, char *argv[])
    myclass m;

    cout <&lt m.getx() <&lt endl;
    cout << m.getx() <&lt endl;

    and the makefile that generates and links main with the shared library:

    main: main.o
    $(CXX) -o main main.o -L. -lshared shared.cpp
    $(CXX) -fPIC -c shared.cpp -o shared.o
    $(CXX) -shared -Wl,-soname, -o shared.o

    $rm *.o *.so

    To actual run 'main' and link with you will probably need to specify the load path (or put it in /usr/local/lib or similar).

    The following specifies the current directory as the search path for libraries and runs main (bash syntax):

    export LD_LIBRARY_PATH=.

    To see that the program is linked with you can try ldd:

    LD_LIBRARY_PATH=. ldd main

    Prints on my machine:

    ~/prj/test/shared$ LD_LIBRARY_PATH=. ldd main => (0xb7f88000) => ./ (0xb7f85000) => /usr/lib/ (0xb7e74000) => /lib/ (0xb7e4e000) => /usr/lib/ (0xb7e41000) => /lib/ (0xb7cfa000)
    /lib/ (0xb7f89000)

  3. Basically, you should include the class' header file in the code where you want to use the class in the shared library. Then, when you link, use the '-l' flag to link your code with the shared library. Of course, this requires the .so to be where the OS can find it. See 3.5. Installing and Using a Shared Library

    Using dlsym is for when you don't know at compile time which library you want to use. That doesn't sound like it's the case here. Maybe the confusion is that Windows calls the dynamically loaded libraries whether you do the linking at compile or run-time (with analogous methods)? If so, then you can think of dlsym as the equivalent of LoadLibrary.

    If you really do need to dynamically load the libraries (i.e., they're plug-ins), then this FAQ should help.

  4. Chapter 1 of C++ Cookbook has several scenarios for building static and dynamic C++ libraries using various build tools, include Make,, and a few IDEs.

  5. nimrodm,

    Lets say you create an object Ab from class A.

    A is defined in a header file h1.h
    A is implemented in a shared library file

    Lets now say that objet Ab is instanciated from a third file main.cpp
    objet Ac is instanciated from a fourth file main2.cpp which also uses

    Will Ac and Ab be a shared object? I'm doing a program where this seems to be the case, but then I might be missing something.