PDA

View Full Version : using shared libraries and dlopen + dlsym



eva69
02-09-2009, 05:08 PM
Hi

I am trying to do a simple program that uses a shared library and calls a function within that library using dlopen() and dlsym()

I seem to have my programs setup up correctly, but from what i've see online i just can't seem to find the correct way to compile these files.

i was looking at this link

http://tldp.org/HOWTO/Program-Library-HOWTO/more-examples.html

but can't get these programs to compile, i was wondering if anyone could help point me in the right direction, my main problem starts with dlopen, is isn't able to open the shared library

Codeplug
02-09-2009, 05:17 PM
Have you read the whole thing?
http://tldp.org/HOWTO/Program-Library-HOWTO/index.html

More resources:
http://www.ibm.com/developerworks/library/l-shobj/
http://www.ibm.com/developerworks/web/library/l-shlibs.html

gg

brewbuck
02-09-2009, 05:46 PM
If the program won't compile, chances are you are not linking with libdl. Add "-ldl" to your compile command.

If it is compiling, but not finding the library, or failing at runtime some other way, post some code and we can look.

eva69
02-09-2009, 07:30 PM
I read it afterwards, i got it to work, my mistake there, i did read the wrong one, however, only the example from the website i linked works, when i try to change the file names to use my library and so on, it gives me the same error, very strange, essentially i did a copy and paste, here's what i have


/* nlcnt.c -- demonstrate dynamic loading and
use of the "hello" routine */


/* Need dlfcn.h for the routines to
dynamically load libraries */
#include <dlfcn.h>

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

/* Note that we don't have to include "libhello.h".
However, we do need to specify something related;
we need to specify a type that will hold the value
we're going to get from dlsym(). */

/* The type "simple_demo_function" describes a function that
takes no arguments, and returns no value: */

typedef void (*simple_demo_function)(void);


int main(void) {
const char *error;
void *module;
simple_demo_function demo_function;

/* Load dynamically loaded library */
module = dlopen("mapping.so", RTLD_LAZY);
if (!module) {
fprintf(stderr, "Couldn't open mapping.so: %s\n",
dlerror());
exit(1);
}

/* Get symbol */
dlerror();
demo_function = dlsym(module, "my_cnt");
if ((error = dlerror())) {
fprintf(stderr, "Couldn't find hello: %s\n", error);
exit(1);
}

/* Now call the function in the DL library */
(*demo_function)();

/* All done, close things cleanly */
dlclose(module);
return 0;
}



/* mapping.c - demonstrate library use. */

#include <stdio.h>

void my_cnt(void) {
printf("test\n");
}



/* mapping.h - demonstrate library use. */


void my_cnt(void);


and i compile these with the follow commands

cc -fPIC -Wall -g -c mapping.c
cc -g -shared -Wl,-soname,mapping.so.0 \-o mapping.so.0.0 mapping.o -lc
/sbin/ldconfig -n .
ln -sf mapping.so.0 mapping.so

cc -Wall -g -c nlcnt.c
cc -g -o nlcnt nlcnt.o -ldl
LD_LIBRARY_PATH="." ./nlcnt

any suggestions?

CornedBee
02-10-2009, 03:12 AM
So what's the message you get?

eva69
02-10-2009, 11:50 AM
the error i get appears as follows:


Couldn't open mapping.so: mapping.so: cannot open shared object file: No such file or directory

now when i do compile everything, mapping.so is clearly present, and as i said, if i run this example, switch the names around so its like the example i linked, it works perfectly, this is very weird

Codeplug
02-10-2009, 12:03 PM
Have you tried this (straight from the Howto if using bash):
> LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./nlct

gg

eva69
02-10-2009, 12:11 PM
yea, same error

root4
02-10-2009, 01:43 PM
make sure each path in LD_LIBRARY_PATH is separated by the character ':', based on the last post you should actually have: export LD_LIBRARY_PATH=".:$LD_LIBRARY_PATH:./nlcnt" or from your post: export LD_LIBRARY_PATH=".:./nlcnt" or just export LD_LIBRARY_PATH=./nlcnt if you just want to use your lib.

Codeplug
02-10-2009, 05:06 PM
./nlcnt is not a path, it's the application which is run on the same line as the LD_LIBRARY_PATH= statement.

You can try exporting it (check your shell's documentation). And double check the value of LD_LIBRARY_PATH to make sure the current directory is a part of it.

gg

brewbuck
02-10-2009, 05:24 PM
cc -g -shared -Wl,-soname,mapping.so.0 \-o mapping.so.0.0 mapping.o -lc


This line looks wrong. What's with that backslash? I suspect that what's happening is that this link command is failing due to the weird argument, and mapping.so.0.0 isn't being produced. Then you symlink it under the wrong name anyway:


ln -sf mapping.so.0 mapping.so

And that 'f' flag is causing ln to not report the error that the file does not exist. Have you checked that mapping.so.0.0 actually exists? Get rid of that backslash, and change you ln command to link mapping.so.0.0 instead of mapping.so.0

eva69
02-11-2009, 12:46 AM
This line looks wrong. What's with that backslash? I suspect that what's happening is that this link command is failing due to the weird argument, and mapping.so.0.0 isn't being produced. Then you symlink it under the wrong name anyway:


ln -sf mapping.so.0 mapping.so

And that 'f' flag is causing ln to not report the error that the file does not exist. Have you checked that mapping.so.0.0 actually exists? Get rid of that backslash, and change you ln command to link mapping.so.0.0 instead of mapping.so.0

thank you so much!

i assumed the website was correct, thanks for pointing that out, it now does what i want it to do

i removed that backslash and linked mapping.so.0.0 instead of mapping.so.0

i did look at the files being created, and mapping.s.0.0 wasn't being created, but in the other example it was, i still find it strange that it worked with one example and not the other, but anywho it works now, thanks for the help again

brewbuck
02-11-2009, 11:17 AM
thank you so much!

i assumed the website was correct, thanks for pointing that out, it now does what i want it to do

i removed that backslash and linked mapping.so.0.0 instead of mapping.so.0

i did look at the files being created, and mapping.s.0.0 wasn't being created, but in the other example it was, i still find it strange that it worked with one example and not the other, but anywho it works now, thanks for the help again

All the ".0.0" and "ln" business is superfluous anyway. You'd do something like that if you were creating a shared library for deployment. But if you're just fooling around, don't bother with "soname" or ".0.0" or anything, just call your library whatever.so

The -fPIC is absolutely necessary, though.

Also, if you load your library with dlopen("./whatever.so") instead of dlopen("whatever.so") then you won't have to mess around with ldconfig or LD_LIBRARY_PATH.

eva69
02-11-2009, 11:50 AM
Also, if you load your library with dlopen("./whatever.so") instead of dlopen("whatever.so") then you won't have to mess around with ldconfig or LD_LIBRARY_PATH.

oh nice, thank you, i was just about to look into that