Link to home
Start Free TrialLog in
Avatar of zulliger
zulliger

asked on

dlsym problem

hi

i'm trying to enable my software to use plugins. i've read a lot about the dynamic loadable libs...
the following problem occurs:
when i compile my small example plugin:

#include <stdio.h>
int
run( )
{
        printf( "hallo!!!!!!!!!!!!!\n\n" );
        return 0;
}

by
gcc -fPIC -DPIC -c main.c
gcc -shared -lstdc++ -o main.so main.o

and also compile my plugin-loader:
#include <dlfcn.h>
#include <stdio.h>
#include <iostream.h>

typedef int entrypoint( );

int
main()
{
        char *errormsg;
        void *module = NULL;
        entrypoint *run = NULL;

        module = dlopen( "/tmp/tmp/main.so", RTLD_NOW );
        //module = dlopen( "/usr/local/lib/libqtgui.so", RTLD_NOW );
//      module = dlopen( "/tmp/tmp/libsuper.so", RTLD_NOW );
        if( !module )
        {
                printf( "superscheisse" );
        }

        run = (entrypoint*) dlsym( module, "run" );
        if( errormsg = dlerror( ) )
        {
                printf( "nei: %s", errormsg );
        } else {
                printf( "aha!\n\n" );
        }
}

by
g++ super.c  -o super -ldl
everyting works fine...

but when i compile the plugin (the first one) - i got an error while dlsym:
./super: undefined symbol: run

there seams to be a problem with the c++ compiler?!

i'm using Mandrake 8.1, g++ version: 2.96

any hints?

thanks, raphael
Avatar of garboua
garboua

1. your library should be named libmain.so
2. well you never told it,super, your program, to use the shared library main.
and I could be wrong
Avatar of zulliger

ASKER

yes... the names are a bit confusing... super.c is my ''main'' -program and main.c is the plugin.

i'm sorry but your solution doesn't seams to work. i changed the following:

 module = dlopen( "/tmp/tmp/libmain.so", RTLD_NOW );
in super.c

and changed the make process to:
  g++ -fPIC -DPIC -c main.c
  g++ -shared -lstdc++ -o libmain.so main.o
and still the same problem: by using gcc instead of g++ it works.

btw: if i rename main.c to main.cpp, but compile the plugin (shared library) with gcc it doesn't works!!!

other tips?

yes... the names are a bit confusing... super.c is my ''main'' -program and main.c is the plugin.

i'm sorry but your solution doesn't seams to work. i changed the following:

 module = dlopen( "/tmp/tmp/libmain.so", RTLD_NOW );
in super.c

and changed the make process to:
  g++ -fPIC -DPIC -c main.c
  g++ -shared -lstdc++ -o libmain.so main.o
and still the same problem: by using gcc instead of g++ it works.

btw: if i rename main.c to main.cpp, but compile the plugin (shared library) with gcc it doesn't works!!!

other tips?

g++ super.c  -o super main.o -ldl
this doesn't helps... the same problems as before.
oops, didn't read carefully:
  g++ super.c  -o super -L. main.so -ldl
anayway, my first suggestion should also work

BTW, you don't have a declaration of run in super.c, add one like
   int run(void);
i'm not sure if you missunderstood the problem: i want to use the main.c as a dynamic loadable plugin (at runtime). isn't the solution you presenting me dynamic linking?

i tried your second tip, but it wasn't successful:

[raphael@sensor tmp]$ g++ super.c -o super -L. main.so -ldl
[raphael@sensor tmp]$ ./super
./super: error while loading shared libraries: main.so: cannot open shared object file: No such file or directory

if you want, i could send the files to you.
> .. missunderstood the problem ..
argh, understood, but gave the wrong answer (Montag war doch gestern:)
Please ignore my previous suggestions, sorry.

But did you read  man dlsym?

...
flag must be either RTLD_LAZY, meaning  resolve undefined
symbols  as  code from the dynamic library is executed, or
RTLD_NOW, meaning resolve  all  undefined  symbols  before
dlopen  returns, and fail if this cannot be done.
...
yea i've read the man pages and also had a book and homepages with examples... the problem is, i've never read something about c++ problems in this context. all examples are programmed in C and i'm assuming my problem is C++(compiler) related...
as I understand *my* man-page, you need to use RTLD_LAZY instead of RTLD_NOW
- the code works with RTLD_NOW when i compile it with gcc instead of g++.
- when i change RTLD_NOW to RTLD_LAZY and compile it again with:
g++ super.c -o super -ldl
and also with:
g++ super.c -o super -L. main.so -ldl
i still get the following error:
./super: undefined symbol: run
respectively:
./super: error while loading shared libraries: main.so: cannot open shared object file: No such file or directory

to make it easier i've put the three testfiles here:
http://www.inetsolutions.ch/zulli/tmp/
i've compiled the plugin by
./compile gcc or
./compile g++
the first works the second doesn't...

i hope now we're getting closer to the solution.
thanks for your effort!
works perfect for me. Compiling either gcc or g++.
If you get superscheisse, then your path to main.so is wrong (ask the programmer :-)

Ok, jokes beside: does not work if main.so is linked using g++. I asume that this is a bug in the g++. If you link using ld (as gcc does) it works.

BTW, I always avoided using compilers for linking, I always use ld to link. Heavan knows ...
sometimes a programmer (espacially a unexperienced one as me) has to print ugly things on the screen :-)

so if you first compile the plugin by g++ and then link it by ld it works?! what are the exactly commands?
g++ -fPIC -DPIC -c main.c
ld -shared -lstdc++ -o main.so main.o
g++ super.c -o super -ldl
# doesn't matter if you use gcc or g++ as compiler for main.c ('cause it's C anyway)
:-(
[raphael@sensor tmp]$ ld -shared -lstdc++ -o main.so main.o
ld: cannot find -lstdc++

'locate libstc++' gives me:
/usr/lib/libstdc++-3-libc6.2-2-2.10.0.so
/usr/lib/gcc-lib/i586-mandrake-linux-gnu/2.96/libstdc++.so
/usr/lib/gcc-lib/i586-mandrake-linux-gnu/2.96/libstdc++.a
/usr/lib/libstdc++-libc6.2-2.so.3
/usr/lib/libstdc++-libc6.2-2.a.3
/usr/lib/libstdc++-3-libc6.2-2-2.10.0.a
/usr/lib/libstdc++-libc6.1-1.so.2
... and some more


when i link without libstdc++ or -lc it doesn't work... (undefined symbol: run)

when i try  ld -shared /usr/lib/libstdc++-3-libc6.2-2-2.10.0.a -o main.so main.o
it also doesn't work (undefined symbol: run)

maybe something with gcc-2.96?
ASKER CERTIFIED SOLUTION
Avatar of ahoffmann
ahoffmann
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
very cool! i read it and it seams to be exactly what i was searching for. i will test it within the next hours and if it works you'll get the points.

thanks a lot!
raphael
if extern C does not work still add this flag to super.c linking "-rdynamic"
it really works! thanks a lot! how did you find this link?