exposing singleton in dynamically loaded library

Started by
5 comments, last by Genjix 18 years, 11 months ago
How would I expose internal functions/globals (i.e my singleton)?


void Foo();
void Bar();

void Foo()
{
	cout << "Foo()\n";
}

void Bar()
{
	cout << "Bar()\n";
}

int main()
{
	// open module
	void *module = dlopen("./hello.so", RTLD_LAZY);
	if(!module)
 	{
		cerr << "error in open: " << dlerror() << "\n";
		exit(-1);
	}

	// can this next 4 lines be done in a simpler way?
	typedef void (*Function)();
	Function function;

	void *pointer = dlsym(module, "hello");
	function = *reinterpret_cast<Function*>(&pointer);

	// check for errors
	const char *error = dlerror();
	if(error)
	{
		cerr << "fatal error: " << error << "\n";
		exit(-1);
	}

	// call the function
	function();

	// close the module
	dlclose(module);

	return 0;
}



#include <iostream>
using namespace std;

void Foo();

extern "C"
{

// i think this needs to be wrapped in extern "C"
void hello()
{
	cout << "hello\n";
	Foo();
}

}



genjix@linux:~/media/tmp/obj/dl> ./a.out
error in open: ./hello.so: undefined symbol: _Z3Foov
Advertisement
I might be wrong cause I haven't used dynamically loaded libraries often...

First, why are you defining Foo() and Bar() in what seems to be your main application? Aren't you trying to load these from the library?

also, in your .so, is there some missing code?

You define void Foo(), but never implement it...

Might be the reason of your error.

Hope that helps

Eric

[Edit: typos]
well, i'm trying to define code inside my dynamically loaded library that can call functions within my main base code (so hello() can access data and call methods from within main code).

I have no trouble loading the library but I can't expose any of the main.cpp functions. I know its possible because I've seen references to it all over the net.
This sounds weird but it helped me once: try putting extern "C" in front of every function instead of using the block syntax.

Linux also has a command nm that shows a binary's symbols.
extern "C" void hello() does not help :(

genjix@linux:~/media/tmp/obj/dl> echo -en "[hello.so]\n\n" > log && nm hello.so>> loggenjix@linux:~/media/tmp/obj/dl> echo -en "[a.out]\n\n" >> log && nm a.out >> log


[hello.so]00001b50 A __bss_start00000780 t call_gmon_start00001b50 b completed.100001a2c d __CTOR_END__00001a24 d __CTOR_LIST__         U __cxa_atexit@@GLIBC_2.1.3         w __cxa_finalize@@GLIBC_2.1.300000920 t __do_global_ctors_aux000007b0 t __do_global_dtors_aux00001b44 d __dso_handle00001a34 d __DTOR_END__00001a30 d __DTOR_LIST__00001a3c A _DYNAMIC00001b50 A _edata00001b58 A _end00000954 T _fini00000820 t frame_dummy00000a20 r __FRAME_END__00000904 t _GLOBAL__I_x00001b30 A _GLOBAL_OFFSET_TABLE_         w __gmon_start__         U __gxx_personality_v0@@CXXABI_1.200000868 T hello0000072c T _init00001a38 d __JCR_END__00001a38 d __JCR_LIST__         w _Jv_RegisterClasses00001b48 d p.0000008ec t __tcf_000001b4c D x         U _Z3Foov000008ae t _Z41__static_initialization_and_destruction_0ii         U _ZNSolsEi@@GLIBCPP_3.20000097c V _ZNSt15basic_streambufIcSt11char_traitsIcEE13_S_pback_sizeE00000980 V _ZNSt15basic_streambufIwSt11char_traitsIwEE13_S_pback_sizeE         U _ZNSt8ios_base4InitC1Ev@@GLIBCPP_3.2         U _ZNSt8ios_base4InitD1Ev@@GLIBCPP_3.2         U _ZSt4cout@@GLIBCPP_3.200001b54 b _ZSt8__ioinit         U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCPP_3.2[a.out]08049d94 A __bss_start08048784 t call_gmon_start08049eb4 b completed.108049c54 d __CTOR_END__08049c4c d __CTOR_LIST__         U __cxa_atexit@@GLIBC_2.1.308049d88 D __data_start08049d88 W data_start         U dlclose@@GLIBC_2.0         U dlerror@@GLIBC_2.0         U dlopen@@GLIBC_2.1         U dlsym@@GLIBC_2.008048aa0 t __do_global_ctors_aux080487b0 t __do_global_dtors_aux08049d8c D __dso_handle08049c5c d __DTOR_END__08049c58 d __DTOR_LIST__08049c64 D _DYNAMIC08049d94 A _edata08049ebc A _end         U exit@@GLIBC_2.008048ac4 T _fini08049c4c A __fini_array_end08049c4c A __fini_array_start08048ae0 R _fp_hw080487f0 t frame_dummy08048c48 r __FRAME_END__080489b4 t _GLOBAL__I__Z3Foov08049d50 D _GLOBAL_OFFSET_TABLE_         w __gmon_start__         U __gxx_personality_v0@@CXXABI_1.208048a98 T __i686.get_pc_thunk.bx0804867c T _init08049c4c A __init_array_end08049c4c A __init_array_start08048ae4 R _IO_stdin_used08049c60 d __JCR_END__08049c60 d __JCR_LIST__         w _Jv_RegisterClasses080489d0 T __libc_csu_fini08048a40 T __libc_csu_init         U __libc_start_main@@GLIBC_2.008048858 T main08049d90 d p.008048760 T _start0804899c t __tcf_00804883a T _Z3Barv0804881c T _Z3Foov0804895e t _Z41__static_initialization_and_destruction_0ii08048b28 V _ZNSt15basic_streambufIcSt11char_traitsIcEE13_S_pback_sizeE08048b2c V _ZNSt15basic_streambufIwSt11char_traitsIwEE13_S_pback_sizeE         U _ZNSt8ios_base4InitC1Ev@@GLIBCPP_3.2         U _ZNSt8ios_base4InitD1Ev@@GLIBCPP_3.208049e28 B _ZSt4cerr@@GLIBCPP_3.208049d98 B _ZSt4cout@@GLIBCPP_3.208049eb8 b _ZSt8__ioinit         U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCPP_3.2


as far as I can tell, it cannot resolve the _Z3Foov symbol :(
I'd try with extern "C" for foo() too, I'm no expert in this area, but it might be the name mangling that foo() has that makes it incompatible with the call in the extern "C" section?

Anyway, really I can't help much than that, wish I helped

Good luck
tried that before... still didn't work. :(

This topic is closed to new replies.

Advertisement