Fla*_*ius 5 c++ linux g++ shared-libraries
我想创建一个能够dlopen()运行一系列库(由我自己编写)的程序,并运行存储在test_suite.so文件内部的全局变量中的所有函数,这是一个以NULL结尾的函数指针数组(函数')签名是我自己预定义的,无需担心).
问题是g ++ mangles变量.该库编译为:
g++ -Wall -shared -rdynamic -fPIC foo.cpp -o foo.so
Run Code Online (Sandbox Code Playgroud)
并且"功能索引"被声明并静态分配为:
const testunit_testcase test_suite = { ... }
Run Code Online (Sandbox Code Playgroud)
然而
objdump -t foo.so | grep test_suite
Run Code Online (Sandbox Code Playgroud)
说明:
0000000000200940 l O .data.rel.ro 0000000000000020 _ZL10test_suite
Run Code Online (Sandbox Code Playgroud)
我需要的是
0000000000200940 l O .data.rel.ro 0000000000000020 test_suite
Run Code Online (Sandbox Code Playgroud)
这样我就可以dlsym(dlh, "test_suite")在程序中dlopen()"荷兰国际集团 foo.so
谢谢
附录
是的,这extern "C"是我尝试过的第一件事:
extern "C" {
const testunit_testcase test_suite[] = {
//TESTUNIT_DEF_TESTCASE(doTest),
{NULL, NULL},
};
}
Run Code Online (Sandbox Code Playgroud)
我在用:
g ++ -v使用内置规范.COLLECT_GCC = g ++ COLLECT_LTO_WRAPPER =/usr/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/lto-wrapper目标: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 = { ... }
}
Run Code Online (Sandbox Code Playgroud)
确实没有工作,但这一作用:
extern "C" const testunit_testcase test_suite = { ... }
Run Code Online (Sandbox Code Playgroud)
我现在的问题:正如我在你的一些答案中所看到的那样,extern "C" { ... }为你附上作品.是否有任何编译器标志可以用来确保test_suite永远不会被破坏,无论使用什么4.x(至少)g ++版本?
问题不在于名称错误.(或者可能不是:公共变量名称通常不会被破坏.)真正的问题是"const"意味着隐式静态,使变量在翻译单元外部不可见.为避免这种情况,必须将变量显式声明为extern.并且"包含括号括起来的声明-seq的链接规范的形式不影响包含的声明是否是定义(3.1);直接包含单个声明的链接规范的形式被视为外部说明符( 7.1.1)为确定所载声明是否为定义." 虽然它似乎没有直接解决你的问题(初始化程序的存在确保声明是一个定义),但它似乎表明了意图:在括号内的连接说明符中,通常的规则适用; 如果链接说明符直接适用于声明,那就好像声明是明确的extern.所以你可以写:
extern "C" {
testunit_testcase const test_suite[] // ...
}
Run Code Online (Sandbox Code Playgroud)
要么
extern "C" testunit_testcase const test_suite[] // ...
Run Code Online (Sandbox Code Playgroud)
但是必须有一个明确适用于定义的extern,以便覆盖"const"的隐式"静态".
| 归档时间: |
|
| 查看次数: |
2945 次 |
| 最近记录: |