32

I have a shared object (a so - the Linux equivalent of a Windows dll) that I'd like to import and use with my test code.

I'm sure it's not this simple ;) but this is the sort of thing I'd like to do..

#include "headerforClassFromBlah.h"

int main()
{
    load( "blah.so" );

    ClassFromBlah a;
    a.DoSomething();
}

I assume that this is a really basic question but I can't find anything that jumps out at me searching the web.

Ben L
  • 6,618
  • 8
  • 39
  • 34
  • Maybe im confused but you don't look like you have enough info there. What does blah.so contain, for example? You sure you aren't just talking about using a reference? – Goz Jul 17 '09 at 08:54
  • What do you mean by "shared" exactly? – Klaim Jul 17 '09 at 08:54
  • Err...so files are not code files, right? Maybe you want to retrieve an object from a .so (shared library) file? – Klaim Jul 17 '09 at 08:56

4 Answers4

50

There are two ways of loading shared objects in C++

For either of these methods you would always need the header file for the object you want to use. The header will contain the definitions of the classes or objects you want to use in your code.

Statically:

#include "blah.h"
int main()
{
  ClassFromBlah a;
  a.DoSomething();
}

gcc yourfile.cpp -lblah

Dynamically (In Linux):

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
    void *handle;
    double (*cosine)(double);
    char *error;
    handle = dlopen ("libm.so", RTLD_LAZY);
    if (!handle) {
        fprintf (stderr, "%s\n", dlerror());
        exit(1);
    }
    dlerror();    /* Clear any existing error */
    cosine = dlsym(handle, "cos");
    if ((error = dlerror()) != NULL)  {
        fprintf (stderr, "%s\n", error);
        exit(1);
    }
    printf ("%f\n", (*cosine)(2.0));
    dlclose(handle);
    return 0;
}

*Stolen from dlopen Linux man page The process under windows or any other platform is the same, just replace dlopen with the platforms version of dynamic symbol searching.

For the dynamic method to work, all symbols you want to import/export must have extern'd C linkage.

There are some words Here about when to use static and when to use dynamic linking.

Salgar
  • 7,687
  • 1
  • 25
  • 39
  • 9
    +1. Maybe worth an explicit mention that dlopen is POSIX, not C or C++. On some platforms there is no dynamic loading, but they're still conforming C++ implementations. – Steve Jessop Jul 17 '09 at 11:14
  • What is the command to build this file, would g++ filename.cpp -L someIncludes -0 file work? –  Jul 17 '09 at 13:30
  • You'll need to link using -ldl too – Ben L Jul 17 '09 at 13:34
  • 2
    Note that the dlsym(handle, "cos") references a C function, so easy to find the name. C++ generates decorations making such code not so easy to write. (at least not without the use of the extern "C" extension so write a C function to get at the C++ function.) – Alexis Wilke Sep 09 '11 at 03:45
  • what does "-lblah" do, can you elaborate – basickarl Nov 30 '14 at 00:53
  • @SteveJessop you're wrong, Windows also supports dynamic loading (runtime linkage). The equivalent on Windows for dlsym is `GetProcAddress([function-name])`and for dlopen you have to use `LoadLibrary([lib-name]|[path-to-lib])` instead of `dlopen([lib-name])` – Sebi2020 Jun 04 '15 at 12:23
9

It depends on the platform. To do it at runtime, on Linux, you use dlopen, on windows, you use LoadLibrary.

To do it at compile time, on windows you export the function name using dllexport and dllimport. On linux, gcc exports all public symbols so you can just link to it normally and call the function. In both cases, typically this requires you to have the name of the symbol in a header file that you then #include, then you link to the library using the facilities of your compiler.

1800 INFORMATION
  • 131,367
  • 29
  • 160
  • 239
5

You need to #include any headers associated with the shared library to get the declrarations of things like ClassFromBlah. You then need to link against the the .so - exactly how you do this depends on your compiler and general instalation, but for g++ something like:

g++ myfile.cpp -lblah

will probably work.

  • I have included the headers and I can compile & link my code with the shared object but I've no idea how to use it and the classes it contains - I didn't make that clear, see my update to code snippet. Any ideas? – Ben L Jul 17 '09 at 09:11
  • 1
    As to how to use the classes it contains, you have to RTFM, I'm afraid. –  Jul 17 '09 at 09:15
  • @neil That is probably the solution Ben needs ... The dlopen accepted answer might be just a misinterpretation of a beginner question (Ben ?) ... @Ben L : If you don't know what are in the .so you will have problem using it with dlsym ;-) – neuro Jul 17 '09 at 14:30
  • 1
    @KarlMorrison -l is the flag to load a shared library. The "blah" in front is the name of the shared library, which in this case he/she used the name of the library that the OP used in his example. – Anoyz Jul 17 '15 at 11:28
  • @Anoyz If only C/C++ could be rewritten to make a little more sense. Thanks for the explanation! – basickarl Jul 17 '15 at 11:31
  • Haha! It's a very low level/high control language, for performance and stability. Other higher-level languages are more suitable and easier to understand. Try python :) Cheers! – Anoyz Jul 17 '15 at 11:42
0

It is -l that link the archive file like libblah.a or if you add -PIC to gcc you will get a 'shared Object' file libblah.so (it is the linker that builds it). I had a SUN once and have build this types of files. The files can have a revision number that must be exact or higher (The code can have changed due to a bug). but the call with parameters must be the same like the output.