Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Shared Library compilation with g++

I'm trying to compile the following simple DL library example code from Program-Library-HOWTO with g++. This is just an example so I can learn how to use and write shared libraries. The real code for the library I'm developing will be written in C++.

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char **argv) {
    void *handle;
    double (*cosine)(double);
    char *error;

    handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
    if (!handle) {
        fputs (dlerror(), stderr);
        exit(1);
    }

    cosine = dlsym(handle, "cos");
    if ((error = dlerror()) != NULL)  {
        fputs(error, stderr);
        exit(1);
    }

    printf ("%f\n", (*cosine)(2.0));
    dlclose(handle);
}

If I compile the program with gcc it works fine.

gcc -o foo foo.c -ldl

When I change the filename and compiler to the following

g++ -o foo foo.cpp -ldl

I get the following error:

foo.cpp:16: error: invalid conversion from 'void*' to 'double (*)(double)'

I understand (I think I understand, correct me if this is wrong) that I can't do an implicit cast from a void pointer in C++, but C lets me, and this is why the above code will compile using gcc but not using g++. So I tried an explicit cast by changing line 16 above to:

cosine = (double *)dlsym(handle, "cos");

With this in place, I get the following error:

foo.cpp:16: error: cannot convert 'double*' to 'double (*)(double)' in assignment

These problems probably have more to do with my own general ignorance of proper C++ coding standards than anything else. Can anyone point me to a good tutorial on developing dynamic libraries for Linux that uses C++ example code?

like image 759
Bill the Lizard Avatar asked Jan 27 '09 15:01

Bill the Lizard


People also ask

What does G do in compiling?

The -g option instructs the compiler to generate debugging information during compilation. In C++, the -g option turns on debugging and turns off inlining of functions. The- g0 (zero) option turns on debugging and does not affect inlining of functions.

What is G ++ compiler?

g++ command is a GNU c++ compiler invocation command, which is used for preprocessing, compilation, assembly and linking of source code to generate an executable file. The different “options” of g++ command allow us to stop this process at the intermediate stage.


1 Answers

C allows implicit casts from void * to any pointer type (including function pointers); C++ requires explicit casting. As leiflundgren says, you need to cast the return value of dlsym() to the function pointer type you need.

Many people find C's function pointer syntax awkward. One common pattern is to typedef the function pointer:

typedef double (*cosine_func_ptr)(double);

You can define your function pointer variable cosine as a member of your type:

cosine_func_ptr cosine;

And cast using the type instead of the awkward function pointer syntax:

cosine = (cosine_func_ptr)dlsym(handle, "cos");
like image 85
Commodore Jaeger Avatar answered Sep 18 '22 14:09

Commodore Jaeger