C++ 使用gcc构建共享库
已解决。请参阅下面的更正(标记为固定)。C++ 使用gcc构建共享库,c++,gcc,shared-libraries,C++,Gcc,Shared Libraries,已解决。请参阅下面的更正(标记为固定)。 // Source file for the static library #include <iostream> using namespace std; #include "static.h" int function_inside_static_lib(int arg1, int arg2) { cout << "In function_inside_static_lib()" << endl;
// Source file for the static library
#include <iostream>
using namespace std;
#include "static.h"
int function_inside_static_lib(int arg1, int arg2)
{
cout << "In function_inside_static_lib()" << endl;
// Return the sum
int result = arg1 + arg2;
return result;
}
// The shared library only has one source file.
// The shared library uses the static one.
#include "static.h"
#include <iostream>
using namespace std;
int function_inside_shared_lib(int arg1, int arg2)
{
cout << "In function_inside_shared_lib()" << endl;
cout << "Calling function_inside_static_lib()" << endl;
int result = function_inside_static_lib(arg1, arg2);
return result;
}
使用gcc创建共享库时遇到问题
我创建了一个小样本项目,它与我正在进行的实际项目的结构非常相似。我已在此处将其作为tar.gz存档提供:
修复:我已在此处提供修复版本:在这个示例项目中,我有一个应用程序(app),它加载我在运行时编写的共享库(libshared.so),并调用共享库定义的函数:function_inside_shared_lib() 反过来,此共享库使用在静态库(libstatic.a)中定义的函数:function\u inside\u static\u lib() 问题是,当我构建共享库时,符号“function\u inside\u shared\u lib”不会被导出。我用“nm”检查了共享库,但符号不在那里。我想知道我用来创建共享库的命令是否正确: g++-g-ggdb-fPIC-rdynamic-I../static-c shared.cpp-o shared.o
g++-g-ggdb-fPIC-rdynamic-shared-L../static-lstatic-o libshared.so 修复:正确的命令是: g++-g-ggdb-fPIC-rdynamic-I../static-c shared.cpp-o shared.o
g++-g-ggdb-fPIC-rdynamic-shared-L../static-o libshared.so shared.o-lstatic 我尝试了使用和不使用-rdynamic以及使用和不使用-fPIC的命令。结果总是一样的 我正在使用Ubuntu 10.04(64位)和g++版本4.4.3 下面是完整的示例项目。(或者你可以使用我文章顶部的链接下载档案) serg@rodent:~/libtest$ls
应用程序共享静态 以下是三个组成部分: 组件1:一个静态库,在\u static\u lib()中定义一个名为function\u的函数。 这包括以下内容: 静态.h
// Header file for the static library
int function_inside_static_lib(int arg1, int arg2);
静态.cpp
// Source file for the static library
#include <iostream>
using namespace std;
#include "static.h"
int function_inside_static_lib(int arg1, int arg2)
{
cout << "In function_inside_static_lib()" << endl;
// Return the sum
int result = arg1 + arg2;
return result;
}
// The shared library only has one source file.
// The shared library uses the static one.
#include "static.h"
#include <iostream>
using namespace std;
int function_inside_shared_lib(int arg1, int arg2)
{
cout << "In function_inside_shared_lib()" << endl;
cout << "Calling function_inside_static_lib()" << endl;
int result = function_inside_static_lib(arg1, arg2);
return result;
}
下面是我用来构建所有这些组件的命令。请注意,我希望调试符号在最终生成的应用程序中可用。理想情况下,我希望能够在应用程序内部进行回溯,并查看共享库和静态库中的符号 1:构建静态库。我想我对这一步没意见: serg@rodent:~/libtest/static$g++-g-ggdb-c static.cpp-o static.o#请参阅下面的固定版本
serg@rodent:~/libtest/static$ar rcs libstatic.a static.o
serg@rodent:~/libtest/static$ls
libstatic.a static.cpp static.h static.o 修复:上面的第一个命令也必须包含-fPIC。正确的命令是 g++-g-ggdb-fPIC-c static.cpp-o static.o 2:构建共享库。我很确定这就是我要出错的地方 serg@rodent:~/libtest/shared$g++-g-ggdb-fPIC-rdynamic-I../static-c shared.cpp-o shared.o
serg@rodent:~/libtest/shared$g++-g-ggdb-fPIC-rdynamic-shared-L../static-lstatic-o libshared.so#固定版本见下文 serg@rodent:~/libtest/shared$ls
libshared.so shared.cpp shared.o 修复:上面的第二个命令应该是: g++-g-ggdb-fPIC-rdynamic-shared-L../static-o libshared.so shared.o-lstatic 此时,如果我运行nm来检查libshared.so中的符号,我在任何地方都看不到函数_在_shared_lib()中,即使使用nm的-a和-D选项。(不过,我确实在shared.o中看到了它) 编辑:使用上面的修复程序,符号在共享库中显示为
\u Z26function\u
3:构建应用程序:
首先,将共享库复制到app文件夹中:
serg@rodent:~/libtest$cp shared/libshared.so app/serg@rodent:~/libtest$cd应用程序
serg@rodent:~/libtest/app$ls
app.cpp libshared.so 现在编译: serg@rodent:~/libtest/app$g++-g-ggdb-ldl-L-L共享app.cpp-o app
serg@rodent:~/libtest/app$ls
app app.cpp libshared.so 如果我尝试运行: serg@rodent:~/libtest/app$。/app
应用程序:加载共享库。
应用程序:在共享库中查找函数库
错误:找不到函数。
/home/serg/libtest/app/libshared.so:未定义符号:函数在共享库中 这是有意义的,因为我也无法在使用nm的_shared_lib()中看到函数_,这意味着我可能在步骤2中错误地构建了共享库 如何在第二步修复命令,以便正确导出共享库中的函数
如果你注意到我做了什么奇怪的事,请随时给我任何其他建议。我还是个初学者。因此,在步骤2中,您没有指定shared.o。因此,不是:
g++ -g -ggdb -fPIC -rdynamic -shared -L ../static -lstatic -o libshared.so
你应该做:
g++ -g -ggdb -fPIC -rdynamic -shared -L ../static shared.o -lstatic -o libshared.so
同样重要的是,shared.o在-lstatic之前。否则,链接器将找不到函数并让它“未定义”。这里有一些错误: libshared.so为空 您的Makefile实际上并没有链接到shared.o中,它只是创建了一个空的共享库。 改变 到 -lstatic必须位于shared/shared.o之后,因为您必须按与其依赖项相反的顺序指定静态库 -共享库中的所有对象文件都需要fPIC 您可以创建一个在静态库中链接的共享库。该静态库还必须使用-fPIC编译,否则您将创建一个共享库,其中某些部分无法重新定位。改变
g++ -g -ggdb -c static/static.cpp -o static/static.o
到
C++符号被损坏
当你从C++代码中创建共享库时,函数名和类似的 这意味着没有与您尝试动态加载的字符串“function\u inside\u static\u lib”匹配的函数名。在静态库上运行nm,您将看到
g++ -g -ggdb -fPIC -rdynamic -shared -Lstatic -o shared/libshared.so shared/shared.o -lstatic
g++ -g -ggdb -c static/static.cpp -o static/static.o
g++ -fPIC -g -ggdb -c static/static.cpp -o static/static.o
function_inside_shared_lib = (int (*)(int, int))dlsym(handle, "_Z26function_inside_static_libii");