【发布时间】:2011-04-05 01:07:15
【问题描述】:
已解决。请参阅下面的更正(标记为 FIXED)。
我在使用 gcc 创建共享库时遇到问题。
我创建了一个小示例项目,它与我正在处理的实际项目的结构非常相似。我在此处将其作为 tar.gz 存档提供:
http://209.59.216.197/libtest.tar.gz
已修复:我在此处提供了固定版本:
http://209.59.216.197/libtest_fixed.tar.gz
在这个示例项目中,我有一个应用程序 (app),它加载我在运行时编写的共享库 (libshared.so) 并调用共享库定义的函数:function_inside_shared_lib()。
反过来,这个共享库使用在静态库 (libstatic.a) 中定义的函数:function_inside_static_lib()。
问题是当我构建共享库时,符号“function_inside_shared_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:一个静态库,定义了一个名为 function_inside_static_lib() 的函数。
这包括以下内容:
serg@rodent:~/libtest$ cd static/ serg@rodent:~/libtest/static$ ls static.cpp static.h
static.h
// Header file for the static library
int function_inside_static_lib(int arg1, int arg2);
static.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;
}
组件 2:使用静态库并定义新函数的共享库。
serg@rodent:~/libtest$ cd shared
serg@rodent:~/libtest/shared$ ls
shared.cpp
shared.cpp
// 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;
}
组件 3:使用共享库的应用程序。
serg@rodent:~/libtest$ cd app
serg@rodent:~/libtest/app$ ls
应用程序.cpp
app.cpp
已修复:由于 C++ 符号被破坏,要搜索的正确函数名称是 _Z26function_inside_static_libii 而不是 function_inside_static_lib
// The application loads the shared library at runtime.
#include <dlfcn.h>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
void *handle;
int (*function_inside_shared_lib)(int, int);
char *error;
int arg1 = 3;
int arg2 = 7;
cout << "app: loading the shared library." << endl;
handle = dlopen ("libshared.so", RTLD_LAZY);
if (!handle) {
cout << "Error: Failed to open shared library." << endl;
cout << dlerror() << endl;
return -1;
}
cout << "app: Looking for function_inside_shared_lib" << endl;
// The next line is now FIXED:
function_inside_shared_lib = (int (*)(int, int))dlsym(handle, "_Z26function_inside_static_libii");
if ((error = dlerror()) != NULL) {
cout << "Error: Could not find the function." << endl;
cout << error << endl;
return -1;
}
cout << "app: Calling function_inside_shared_lib(" << arg1 << ", " << arg2 << ")" << endl;
int result = (*function_inside_shared_lib)(arg1, arg2);
cout << "app: The result is " << result << endl;
dlclose(handle);
return 0;
}
这是我用来构建所有这些组件的命令。请注意,我希望调试符号在最终生成的应用程序中可用。理想情况下,我希望能够在应用程序内进行回溯,并查看共享库和静态库中的符号。
1:构建静态库。我觉得这一步没问题:
serg@rodent:~/libtest/static$ g++ -g -ggdb -c static.cpp -o static.o # 查看下面的FIXED版本
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 # FIXED 版本见下文 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 中的符号,我在任何地方都看不到 function_inside_shared_lib(),即使使用 nm 的 -a 和 -D 选项也是如此。 (但是,我确实在 shared.o 中看到了它)。
编辑:通过上述修复,符号显示为_Z26function_inside_shared_libii。
3:构建应用程序:
首先,将共享库复制到app文件夹中:
serg@rodent:~/libtest$ cp shared/libshared.so app/
serg@rodent:~/libtest$ cd app
serg@rodent:~/libtest/app$ ls
app.cpp libshared.so
现在编译:
serg@rodent:~/libtest/app$ g++ -g -ggdb -ldl -L。 -lshared app.cpp -o 应用
serg@rodent:~/libtest/app$ ls
app app.cpp libshared.so
如果我尝试运行:
serg@rodent:~/libtest/app$ ./app
应用程序:加载共享库。
应用程序:寻找 function_inside_shared_lib
错误:找不到函数。
/home/serg/libtest/app/libshared.so:未定义符号:function_inside_shared_lib
这是有道理的,因为我也无法使用 nm 看到 function_inside_shared_lib(),这意味着我可能在第 2 步中错误地构建了共享库。
如何在第二步中修复我的命令,以便正确导出 function_inside_shared_lib?
如果您发现我在做任何奇怪的事情,请随时给我任何其他建议。我还是个初学者。
【问题讨论】:
-
那个构建共享对象库的命令看起来不对——它没有提到shared.o。你输入正确了吗?
-
这是一个问题还是十七个问题或十七个答案?我不能再说什么了……
标签: c++ gcc shared-libraries