Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ dlsym()';在C++;_C++_Linux_G++_Shared Libraries - Fatal编程技术网

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()
'ing
foo.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[] // ...