C++ dlsym()';在C++;
我想制作一个能够C++ dlsym()';在C++;,c++,linux,g++,shared-libraries,C++,Linux,G++,Shared Libraries,我想制作一个能够dlopen()一系列库(我自己编写)的程序,并运行该.so文件中名为test\u suite的全局变量中存储的所有函数,该文件是一个以NULL结尾的函数指针数组(函数的签名由我自己预定义,不必担心) 问题是g++损坏了该变量。库编译为: g++ -Wall -shared -rdynamic -fPIC foo.cpp -o foo.so “函数索引”静态声明和分配为: const testunit_testcase test_suite = { ... } 然而 显示:
dlopen()
一系列库(我自己编写)的程序,并运行该.so文件中名为test\u suite
的全局变量中存储的所有函数,该文件是一个以NULL结尾的函数指针数组(函数的签名由我自己预定义,不必担心)
问题是g++损坏了该变量。库编译为:
g++ -Wall -shared -rdynamic -fPIC foo.cpp -o foo.so
“函数索引”静态声明和分配为:
const testunit_testcase test_suite = { ... }
然而
显示:
0000000000200940 l O .data.rel.ro 0000000000000020 _ZL10test_suite
我需要的是
0000000000200940 l O .data.rel.ro 0000000000000020 test_suite
因此我可以在程序中dlopen()
'ingfoo.So
谢谢
附录 是的,
extern“C”
是我尝试的第一件事:
extern "C" {
const testunit_testcase test_suite[] = {
//TESTUNIT_DEF_TESTCASE(doTest),
{NULL, NULL},
};
}
我正在使用:
g++-v使用内置规格。
收集\u GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/LTO-WRAPPER
目标:x86_64-unknown-linux-gnu
配置有:
/构建/src/gcc-4.5-20110127/configure
前缀=/UR——使能语言= C、C++、FORTRAN、Objc、Obj-C++、艾达
--启用共享--enable threads=posix--enable--uuuuuucxa_atexit--enable clocale=gnu--enable gnu unique object--enable lto--enable plugin--enable gold--plugin ld=ld.gold--disable multilib--disable libstdcxx pch--system zlib with ppl--with cloog include=/usr/include/cloog ppl
--libdir=/usr/lib--libexecdir=/usr/lib--mandir=/usr/share/man--infodir=/usr/share/info线程模型:posixgcc版本4.5.2
20110127(预发布)(通用条款)
附录2 不管什么原因
extern "C" {
const testunit_testcase test_suite = { ... }
}
不起作用,但这一个起作用:
extern "C" const testunit_testcase test_suite = { ... }
我现在的问题:正如我在你的一些答案中所看到的,附上
extern“C”{…}
适合你。是否有任何编译器标志我可以用来确保test\u suite
永远不会被损坏,不管是什么4.x(至少)使用g++版本? 你使用C++编译器,所以名称会被修改。尝试使用<代码> GCC < /C>(如果可能)或使用< /P>
extern“C”
将停用名称损坏。不要使该变量为静态变量
static
意味着变量是当前编译单元的本地变量,这就是g++修改其名称的原因。如果希望变量可以“从外部”访问,则不应将其设置为static
。因此,在.cpp文件中,定义变量如下:
const testunit_testcase test_suite = { ... }
如果您还在相应的.h文件中声明变量,请进行该声明extern
:
extern const testunit_testcase test_suite;
这个
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\u suite
,它根本不会被导出。这是有意义的,因为文件或命名空间范围的常量意味着静态。这没有意义,因为我希望extern“C”
块“计数”为此,我不知道这是否是一个gcc错误。你能将你的问题缩小到类似的大小吗?问题不是名称混乱。(或者可能不是:public)
变量名通常不会损坏。)真正的问题是
“const”表示隐式静态,使变量在外部不可见
转换单位。为了避免这种情况,变量必须显式
声明的extern.和“包含
大括号括起的声明seq不影响
声明是否为定义(3.1);声明的形式
直接包含单个声明的链接规范是
作为外部说明符(7.1.1)处理,以确定
所包含的声明是否为定义
似乎没有直接解决您的问题(存在
初始值设定项确保声明是一个定义),看起来
为了表明意图:在大括号内的链接说明符中
通常规则适用;如果链接说明符直接应用于
声明,就好像声明是显式的外部声明。所以
您可以写:
extern "C" {
testunit_testcase const test_suite[] // ...
}
或
但必须有一个明确适用于定义的外部条件,
为了覆盖“const”的隐式“static”1.如果希望库外的东西使用它,为什么要将其设置为static
?2.即使使用extern“C”
,也会得到损坏的名称?是的,虽然我有extern“C”,但我得到了损坏的名称。对不起“static”,它是在我尝试不使用它时留下的,但我仍然将它弄坏。如果它在外部“C”之后仍然损坏,则它不会被重建,或者您定义了相同的符号elsewhere@nos:或者正如你在问题的“附录2”中所看到的,extern“C”{foo}
与extern“C”不同foo
这就是它的定义,只是在我的问题中被编辑过的常量。问题仍然存在。@Flavius:对我来说objdump
显示了一个未修改的测试套件
符号名,如果变量未声明为静态
,如果变量为静态
,那么\uzl10test套件
,您是否使用t同一版本的g++?我做的和你在当前问题状态下看到的完全一样。我还用nm
测试了它-名称被弄乱了。dlsym(dlh,“test_suite”)
也返回NULL
。@Flavius:我没有尝试过你使用的快照,但已经尝试过我安装的版本(v4.4.5和v4.5.1)。此外,我没有使用您的类型test\u suite
,而是一个自定义结构,但我认为这不会有什么不同。哦,我刚刚用与您刚才相同的观察结果编辑了我的问题。因此,是的,我能够复制它。您使用的是什么版本的g++?gcc版本4.3.2(Debian 4.3.2-1.1)去掉常量
,并通过扩展隐式静态
也有效(w
~/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 "C" {
testunit_testcase const test_suite[] // ...
}
extern "C" testunit_testcase const test_suite[] // ...