Solved

dlsym problem

Posted on 2002-03-18
20
338 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 51

Expert Comment

by:ahoffmann
Comment Utility
g++ super.c  -o super main.o -ldl
0
 

Author Comment

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

Expert Comment

by:ahoffmann
Comment Utility
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
Comment Utility
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
Comment Utility
> .. 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
Comment Utility
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
Comment Utility
as I understand *my* man-page, you need to use RTLD_LAZY instead of RTLD_NOW
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:zulliger
Comment Utility
- 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
:-(
[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
Comment Utility
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
Comment Utility
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
Comment Utility
if extern C does not work still add this flag to super.c linking "-rdynamic"
0
 

Author Comment

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

Expert Comment

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

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
In this article you will learn how to create a free basic website on Bitbucket, a git service provider. Polymer creates dynamic HTML components, which allow more flexibility than static HTML. This tutorial uses Ubuntu Linux but can also be done on W…
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…
This video discusses moving either the default database or any database to a new volume.

743 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now