Solved

dlsym problem

Posted on 2002-03-18
20
340 Views
Last Modified: 2013-11-18
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
0
Comment
Question by:zulliger
  • 10
  • 8
  • 2
20 Comments
 
LVL 5

Expert Comment

by:garboua
ID: 6878239
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
0
 

Author Comment

by:zulliger
ID: 6878278
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?

0
 

Author Comment

by:zulliger
ID: 6878434
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?

0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 51

Expert Comment

by:ahoffmann
ID: 6879196
g++ super.c  -o super main.o -ldl
0
 

Author Comment

by:zulliger
ID: 6879214
this doesn't helps... the same problems as before.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 6879225
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);
0
 

Author Comment

by:zulliger
ID: 6879246
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.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 6879283
> .. 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.
...
0
 

Author Comment

by:zulliger
ID: 6879289
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...
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 6879303
as I understand *my* man-page, you need to use RTLD_LAZY instead of RTLD_NOW
0
 

Author Comment

by:zulliger
ID: 6879329
- 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!
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 6879397
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 ...
0
 

Author Comment

by:zulliger
ID: 6879431
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?
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 6879445
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)
0
 

Author Comment

by:zulliger
ID: 6879465
:-(
[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?
0
 
LVL 51

Accepted Solution

by:
ahoffmann earned 200 total points
ID: 6879522
aah, I see: it's the damn c++ name mangling :(
If main.so is linked and not loaded, the "extern C" in super.c would solve the problem.
With dlopen() this does no longer work, you need a wrapper for calling function with mangled names, using the unmangled name.
Don't have a working example right now, but following might help:
  http://www.csn.ul.ie/~caolan/Fragments/c++dl.html

If you can life with a dirty hack (not portable at all), simply check with   nm -gop main.so|grep T  which is the mangled name, and use that in super.c. Not recommendet.
0
 

Author Comment

by:zulliger
ID: 6879537
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
0
 
LVL 5

Expert Comment

by:garboua
ID: 6879608
if extern C does not work still add this flag to super.c linking "-rdynamic"
0
 

Author Comment

by:zulliger
ID: 6879621
it really works! thanks a lot! how did you find this link?
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 6879641
http://www.google.com/search?q="c++"+shared+dlopen
0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Equivalent solution for gettimezoneinformation 12 120
IIS 7.5 - Security 2 106
updating the repos in yum 4 112
Error while installing rpm 1 82
The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
Before we dive into the marketing strategies involved with creating an effective homepage, it’s crucial that EE members know what a homepage is. In essence, a homepage is the introductory, or default page, of a website that typically highlights the …
The purpose of this video is to demonstrate how to set up the WordPress backend so that each page automatically generates a Mailchimp signup form in the sidebar. This will be demonstrated using a Windows 8 PC. Tools Used are Photoshop, Awesome…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question