How do I load a shared object in C++?
Asked Answered
B

4

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.

Boyt answered 17/7, 2009 at 8:50 Comment(3)
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?Lapotin
What do you mean by "shared" exactly?Anklebone
Err...so files are not code files, right? Maybe you want to retrieve an object from a .so (shared library) file?Anklebone
M
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.

Mcminn answered 17/7, 2009 at 9:6 Comment(6)
+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.Allain
What is the command to build this file, would g++ filename.cpp -L someIncludes -0 file work?Gerstein
You'll need to link using -ldl tooBoyt
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.)Womenfolk
what does "-lblah" do, can you elaborateSyne
@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])Burchell
L
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.

Listlessness answered 17/7, 2009 at 8:56 Comment(0)
N
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.

Nickolas answered 17/7, 2009 at 8:57 Comment(6)
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?Boyt
As to how to use the classes it contains, you have to RTFM, I'm afraid.Nickolas
@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 ;-)Municipalize
@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.Litigation
@Litigation If only C/C++ could be rewritten to make a little more sense. Thanks for the explanation!Syne
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!Litigation
S
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.

Sty answered 10/7, 2017 at 12:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.