dynamically loading libraries

Started by
2 comments, last by Genjix 18 years, 11 months ago

#include <dlfcn.h>

#include <iostream>
using namespace std;

int main()
{
	// open module
	void *module = dlopen("hello.o", 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;
}

ok, so i use

#include <iostream>
using namespace std;

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


genjix@linux:~/media/tmp/obj/dl> g++ dynamic.cpp -ldl
genjix@linux:~/media/tmp/obj/dl> g++ -c hello.cpp
genjix@linux:~/media/tmp/obj/dl> ./a.out
error in open: hello.o: cannot open shared object file: No such file or directory
also if i try using c object file

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


genjix@linux:~/media/tmp/obj/dl> g++ dynamic.cpp -ldl
genjix@linux:~/media/tmp/obj/dl> gcc -c helloc.c
genjix@linux:~/media/tmp/obj/dl> ./a.out
error in open: hello.o: cannot open shared object file: No such file or directory
why am I getting these errors? interestingly if i open "./hello.o" I get this

genjix@linux:~/media/tmp/obj/dl> g++ dynamic.cpp -ldl
genjix@linux:~/media/tmp/obj/dl> ./a.out
error in open: ./hello.o: only ET_DYN and ET_EXEC can be loaded
...
Advertisement
you cannot open object files. you have to create a dso (dynamic shared object) also called library

with:
g++ -shared -o hello.so hello.cpp

the library must be visible to the runtime linker somehow. so you got 3 options
- put it in a standard path
- hardcode the path in your executable
- define the LD_LIBRARY_PATH envvar
- or play with the rpath option

yes when using c++ you need to extern "C" the functions

so the easiest way with the dso path hardcoded to the CWD
int main(){...	void *module = dlopen("./hello.so", RTLD_LAZY);...}


extern "C" void hello(){	cout << "hello\n";}


and compile with

~$ g++ dynamic.cpp -ldl
~$ g++ -o hello.so -shared hello.cpp
~$ ./a.out
Quote:Original post by Anonymous Poster
the library must be visible to the runtime linker somehow. so you got 3 options


lol, i cannot count, you got 4 options of course ^^
wow, thank you AP (i take it you're the AP without the account who always posts here?). Thanks.

I have another question. 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";}// rest of main.cpp


#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.outerror in open: ./hello.so: undefined symbol: _Z3Foov


This topic is closed to new replies.

Advertisement