我想创建一个能够dlopen()
一系列库(由我自己编写)的程序,并运行存储在.so文件中名为test_suite
的全局变量中的所有函数,是一个以NULL结尾的函数指针数组(函数的签名由我自己预定义,无需担心)。
问题是g ++ mangles变量。该库编译为:
g++ -Wall -shared -rdynamic -fPIC foo.cpp -o foo.so
并声明“函数索引”并静态分配为:
const testunit_testcase test_suite = { ... }
还
objdump -t foo.so | grep test_suite
所示:
0000000000200940 l O .data.rel.ro 0000000000000020 _ZL10test_suite
我需要的是
0000000000200940 l O .data.rel.ro 0000000000000020 test_suite
所以我可以在dlsym(dlh, "test_suite")
'dlopen()
foo.so
由于
附录
是的,extern "C"
是我尝试过的第一件事:
extern "C" {
const testunit_testcase test_suite[] = {
//TESTUNIT_DEF_TESTCASE(doTest),
{NULL, NULL},
};
}
我正在使用:
g ++ -v 使用内置规格。 COLLECT_GCC =克++ COLLECT_LTO_WRAPPER = / usr / lib中/ GCC / x86_64的未知-Linux的GNU / 4.5.2 / LTO-包装 目标:x86_64-unknown-linux-gnu 配置为: /build/src/gcc-4.5-20110127/configure --prefix = / usr --enable-languages = c,c ++,fortran,objc,obj-c ++,ada --enable-shared --enable-threads = posix --enable -__ cxa_atexit --enable -clocale = gnu --enable-gnu-unique-object --enable -lto --enable-plugin --enable-gold - with-plugin-ld = ld.gold --disable-multilib --disable-libstdcxx-pch --with-system-zlib --with-ppl --with-cloog --with-cloog-include = / usr / include / cloog-PPL --libdir = / usr / lib --libexecdir = / usr / lib --mandir = / usr / share / man --infodir = / usr / share / info线程模型:posix gcc版本4.5.2 20110127(预发行)(GCC)
附录2
无论出于何种原因
extern "C" {
const testunit_testcase test_suite = { ... }
}
不工作,但这个确实:
extern "C" const testunit_testcase test_suite = { ... }
我现在的问题:正如我在您的一些答案中所看到的,附上extern "C" { ... }
可以为您效劳。是否有任何编译器标志可用于确保test_suite
永远不会被破坏,无论使用什么4.x(至少)g ++版本?
答案 0 :(得分:8)
问题不在于名称错误。 (或者可能不是:公众 变量名通常不会被破坏。)真正的问题是 “const”表示隐式静态,将变量外部呈现为不可见 翻译单位。为避免这种情况,必须明确地使用变量 宣布外部。和“包含的链接规范的形式 一个括号括起来的声明-seq不影响是否包含 声明是否定义(3.1);的形式 直接包含单个声明的linkage-specification是 为确定目的而被视为外部指定者(7.1.1) 包含的声明是否是一个定义。“哪一个,而它 似乎没有直接解决你的问题(存在 初始化程序确保声明是一个定义),看起来确实如此 表示意图:在括号内的连接说明符中, 通常的规则适用;如果链接说明符直接适用于 声明,就好像声明是明确的extern。那么你 可写:
extern "C" {
testunit_testcase const test_suite[] // ...
}
或
extern "C" testunit_testcase const test_suite[] // ...
但是必须有一个明确适用于定义的extern, 为了覆盖“const”的隐式“静态”。
答案 1 :(得分:1)
这个
x.cxx:
extern "C"
{
extern const int test_suite[] = { 0 };
}
适合我:
~/ec% g++ -Wall -rdynamic -shared x.cxx -o x.so
~/ec% objdump -t x.so | grep test_suite
00000444 g O .rodata 00000004 test_suite
如果我不extern
test_suite
,则根本不会导出。这是有道理的,因为文件或命名空间范围的const意味着static
。它没有意义,因为我希望extern "C"
块能够“计数”。我不知道这是不是一个gcc bug。你能把你的问题减少到类似的东西吗?
答案 2 :(得分:0)
您正在使用C ++编译器,因此名称受到严重破坏。尝试使用gcc
(如果可能)或使用
extern "C" {
const testunit_testcase test_suite = { ... }
}
extern "C"
停用名称修改。
答案 3 :(得分:-1)
不要使变量static
。
static
表示变量是当前编译单元的本地变量,这就是g ++修改其名称的原因。如果您希望“从外部”访问变量,则不应将其变为static
。因此,在.cpp文件中,定义如下变量:
const testunit_testcase test_suite = { ... }
如果您还在相应的.h文件中声明变量,请声明extern
:
extern const testunit_testcase test_suite;