在
C++
中,函数用
dlsym
加载,就像
C
中一样。不过,该函数要用
extern "C"
限定符声明
以防止其符号名被
mangle
。
示例
1.
加载函数
代码
:
//----------
//main.cpp:
//----------
#include <iostream>
#include <dlfcn.h>
int main() {
using std::cout;
using std::cerr;
cout << "C++ dlopen demo\n\n";
// open the library
cout << "Opening hello.so...\n";
void* handle = dlopen("./hello.so", RTLD_LAZY);
if (!handle) {
cerr << "Cannot open library: " << dlerror() << '\n';
return 1;
}
// load the symbol
cout << "Loading symbol hello...\n";
typedef void (*hello_t)();
// reset errors
dlerror();
hello_t hello = (hello_t) dlsym(handle, "hello");
const char *dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol 'hello': " << dlsym_error <<'\n';
dlclose(handle);
return 1;
}
// use it to do the calculation
cout << "Calling hello...\n";
hello();
// close the library
cout << "Closing library...\n";
dlclose(handle);
}
//----------
// hello.cpp:
//----------
#include <iostream>
extern "C" void hello() {
std::cout << "hello" << '\n';
}
在
hello.cpp
中函数
hello
被定义为
extern "C"
。它在
main.cpp
中被
dlsym
调用。
函数必须以
extern "C"
限定,否则我们无从知晓其符号名。
警告:
extern "C"
的声明形式有两种:
上面示例中使用的那种内联(
inline
)形式
extern "C"
,
还有只用花括号的
extern "C" { ... }
这种。
第一种内联形式声明包含两层意义:外部链接
(extern linkage)
和
C
语言链接
(language
linkage)
,
而第二种仅影响语言链接。
下面两种声明形式等价:
代码
:
extern "C" int foo;
extern "C" void bar();
和代码
:
extern "C" {
extern int foo;
extern void bar();
}
对于函数来说,
extern
和
non-extern
的函数声明没有区别,但对于变量就有不同了。
如果您声明变量,请牢记:
代码
:
extern "C" int foo;
和代码
:
extern "C" {
int foo;
}
是不同的物事
(
译者注:简言之,前者是个声明
;
而后者不仅是声明,也可以是定义
)
。
进一步的解释请参考
[ISO14882],7.5,
特别注意第
7
段
;
或者参考
[STR2000]
,
9.2.4
。
在用
extern
的变量寻幽访胜之前,请细读
“
其他
”
一节中罗列的文档。