dlsym() not finding symbols

Oct 30, 2008 at 2:29pm
Hi,
I've just been playing around with dlopen() and dlsym(), and run into a problem. dlopen() apparently loads the shared library without any trouble. But dysym() can't seem to find any of its symbols.

For reference, the code for the shared library is:

1
2
3
4
5
6
#include <stdio.h>

void testFunction()
{
	printf("testFunction\n");
}


The commandline I'm using to compile it is:

 
g++ -fPIC -shared ./testLibrary.cpp -o ./testLibrary.so


The program that does the loading is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <dlfcn.h>

int main(int lArgCount, char** lArgs)
{
	// Load library
	void* lHandle = dlopen("./testLibrary.so", RTLD_LAZY | RTLD_GLOBAL);
	
	// Do some error checking
	char* lError = dlerror();
	if (lError)
	{
		// This error doesn't get hit
		printf("Error: %s\n", lError);
		return 1;
	}
	
	// Load symbol
	dlsym(lHandle, "testFunction");
	
	// Do some error checking
	lError = dlerror();
	if (lError)
	{
		// This error ~does~ get hit
		printf("Error: %s\n", lError);
		return 1;
	}

	return 0;
}


And the compiler commandline for that is:

 
g++ ./testProgram.cpp -ldl -o testProgram


When I run testProgram it finds and loads testLibrary.so but spits out the error:

 
Error: ./testLibrary.so: undefined symbol: testFunction


So I ran nm ./testLibrary.so -DC (D for dynamic exports, C for name de-mangling) and I get:

1
2
3
4
5
6
7
8
9
10
11
         w _Jv_RegisterClasses
000004ac T testFunction()
000016c0 A __bss_start
         w __cxa_finalize
         w __gmon_start__
         U __gxx_personality_v0
000016c0 A _edata
000016c4 A _end
00000514 T _fini
0000039c T _init
         U puts


And, oh look, second line down is testFunction!

So I guess I'm asking, is there anything glaringly obvious that I'm missing?
It's such a simple piece of code, so I think I must be giving the compiler the wrong info...

Thanks in advance to anyone who drops by with ideas.

~Alice
Oct 30, 2008 at 4:32pm
You are trying to compile a .cpp directly into a library. I think you need a compile step and a separate link step.

g++ -c -fPIC testLibrary.cpp -o testLibrary.o
g++ -shared -o testLibrary.so testLibrary.o
Oct 30, 2008 at 6:19pm
Thanks for your reply :)

I split the build up into the two stages, but still have the same problem.

nm seems to say that the symbols are "exported", but is it possible they're not properly exposed?

~Alice
Oct 30, 2008 at 6:22pm
It might be a name-mangling problem.

Can you extern "C" testFunction() in the header file?
Oct 30, 2008 at 6:39pm
Oh oh oh, that worked! *bounce*

Thank you :P

If it's the C++ name mangling. Is there a neat way to get it working without the extern "C"? Like an on-the-fly C++ name mangler that I'd plug into dlsym(). Errm, something like: dlsym( mangle( buff, "non-mangled name" ) ).
As I understand it, libdl is a little outdated though, maybe someone will write a new one some time... I also notice dlopen() and dlsym() cause valgrind to get a little upset.

Thanks again.

~Alice
Oct 30, 2008 at 8:21pm
I'm not aware of any.

cxxabi.h defines the demangle function, but not the inverse...
Topic archived. No new replies allowed.