Description
This is a sample of how C++ call a dlopen function.
1. mypgm.cpp : the main program
2. mylib.cpp: the main library
mypgm.cpp
#include <stdio.h>
#include <dlfcn.h>
typedef char * (* myFun_t)(const char *, int &);
const char * LIB = "libmylib.so";
const char * FUN = "myFun";
//const char * FUN = "_Z5myFunPKcRi";
int main(int argc, char * argv[]) {
void * handle = dlopen(LIB, RTLD_NOW);
if (handle == NULL) {
printf("Cannot load library: %s\n", LIB);
return -1;
}
myFun_t myFun = (myFun_t) dlsym(handle, FUN);
if (myFun == NULL) {
printf("Cannot get function: %s\n", FUN);
return -1;
}
for (int i = 0; i < 3; i++) {
int length = i;
char * buffer = myFun("any", length);
if (buffer == NULL) {
printf("Failed to call myFun\n");
return -1;
}
else {
printf("CALLER: myFun() return [%d],[%s]\n", length, buffer);
}
}
int ret = dlclose(handle);
if (ret != 0) {
printf("Cannot call dlclose\n");
return -1;
}
return 0;
}mylib.cpp
#include <stdio.h>
//extern "C" char * myFun(const char * filename, int & len);
//extern "C" { char * myFun(const char * filename, int & len); }
extern "C"
char * myFun(const char * filename, int & len) {
static int count = 0;
printf("CALLEE: myFun(len=[%d]), count=[%d]\n", len, ++count);
len = count;
char * ret = "aaa";
return ret;
}makefile
1
2 TARGET=mypgm libmylib.so
3
4 all: $(TARGET)
5
6 mypgm: mypgm.cpp
7 g++ -o $@ $< -ldl
8
9 libmylib.so: mylib.cpp
10 g++ -fPIC -shared -o $@ $<
11
12 .PHONY: clean
13
14 clean:
15 -rm -rf $(TARGET)
* Execute
$ make g++ -o mypgm mypgm.cpp -ldl g++ -fPIC -shared -o libmylib.so mylib.cpp $ ./mypgm CALLEE: myFun(len=[0]), count=[1] CALLER: myFun() return [1],[aaa] CALLEE: myFun(len=[1]), count=[2] CALLER: myFun() return [2],[aaa] CALLEE: myFun(len=[2]), count=[3] CALLER: myFun() return [3],[aaa]
C++ mangle
The function myFun defined in mylib.cpp must be declared with "extern C", otherwise, the caller could not find the symbol, because C++ will mangle the symbol name.
Take above example: if there is no "extern C", the myFun function will be given a name as "_Z5myFunPKcRi", so when caller (mypgm) use
myFun_t myFun = (myFun_t) dlsym(handle, "myFun") to find the function symbol, it will not get the expected result, instead the caller can use
myFun_t myFun = (myFun_t) dlsym(handle, "_Z5myFunPKcRi"); to get the correct function.
The mangled symbol name can be get through:
$ nm libmylib.so | grep myFun
00000000000005ac T _Z5myFunPKcRi
0000000000200914 b _ZZ5myFunPKcRiE5count
本文介绍了一个 C++ 程序如何使用动态链接库 (DLL) 的示例。通过创建一个简单的库文件 libmylib.so 和调用程序 mypgm,演示了如何在运行时加载和调用库中的函数 myFun。文章还讨论了 C++ 符号名称修饰的问题及解决方法。

被折叠的 条评论
为什么被折叠?



