解决了的。请参阅下面的更正(标记为“已修复”)。
我无法使用gcc创建共享库。
我创建了一个小的示例项目,它与我正在处理的实际项目的结构非常相似。我已将其作为tar.gz存档提供:
http://209.59.216.197/libtest.tar.gz
修正:我在这里提供了修正版本:
http://209.59.216.197/libtest_fixed.tar.gz
在这个示例项目中,我有一个应用程序(app),它加载我在运行时编写的共享库(lib shared.so),并调用共享库定义的函数:function_inside_shared_lib()。
反过来,这个共享库使用在静态库(lib static.a)中定义的函数:在静态库()中定义的函数。
问题是当我构建共享库时,“在共享库中的函数”符号不会被导出。我用“nm”检查了共享库,但符号不在那里。我想知道我用来创建共享库的命令是否正确:
g++-g-ggdb-fpic-rdynamic-i../static-c shared.cpp-o shared.o
g++-g-ggdb-fpic-rdynamic-shared-l../static-l static-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-l static
我使用和不使用-rdynamic以及-fpic尝试了这些命令。结果总是一样的。
我将Ubuntu10.04(64位)与G++4.4.3版结合使用。
接下来是完整的示例项目。(或者你可以使用我帖子顶部的链接下载归档文件)。
serg@啮齿动物:~/libtest$ls
应用程序共享静态
以下是三个组成部分:
组件1:一个静态库,它定义了一个在静态库()内名为函数_的函数。
.
这包括以下内容:
serg@rodent:~/libtest$ cd static/
serg@rodent:~/libtest/static$ ls
static.cpp static.h
静态的
// Header file for the static library
int function_inside_static_lib(int arg1, int arg2);
静力触探
// 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@啮齿动物:~/libtest$cd共享
serg@啮齿动物:~/libtest/共享$ls
共享CPP
共享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@啮齿动物:~/libtest$cd app
serg@啮齿动物:~/libtest/app$ls
App.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@啮齿动物:~/libtest/static$g+-g-ggdb-c static.cpp-o static.o请参见下面的固定版本
serg@啮齿动物:~/libtest/static$ar rcs libstatic.a static.o
serg@啮齿动物:~/libtest/static$ls
libstatic.a static.cpp static.h静态.o
修正:上面的第一个命令也必须包括-fpic。正确的命令是
G++-G-GGDB-FPIC-C static.cpp-O static.O(静态)
2:建立共享库。我很确定这就是我要出错的地方。
serg@啮齿动物:~/libtest/shared$g+-g-ggdb-fpic-rdynamic-i../static-c shared.cpp-o shared.o
serg@啮齿动物:~/libtest/shared$g+-g-ggdb-fpic-rdynamic-shared-l../static-l static-o libshared.so固定版本见下文
serg@啮齿动物:~/libtest/共享$ls
libshared.so shared.cpp共享.o
修正:上面的第二个命令应该是:
g++-g-ggdb-fpic-rdynamic-shared-l./static-o libshared.so shared.o-l static
此时,如果我运行nm来检查lib shared.so中的符号,我在任何地方都看不到函数_shared_lib(),即使有nm的-a和-d选项。(不过,我确实在shared.o中看到了它)。
编辑:使用上面的修复,符号显示为
_Z26function_inside_shared_libii
.
3:构建应用程序:
首先,将共享库复制到应用程序文件夹中:
serg@啮齿动物:~/libtest$cp共享/libshared.so应用程序/
serg@啮齿动物:~/libtest$cd app
serg@啮齿动物:~/libtest/app$ls
app.cpp libshared.so版本
现在编译:
serg@啮齿动物:~/libtest/app$g++-g-ggdb-ldl-l.-lshared app.cpp-o app
serg@啮齿动物:~/libtest/app$ls
应用app.cpp libshared.so
如果我尝试跑步:
serg@啮齿动物:~/libtest/app$/app
应用:加载共享库。
应用程序:在共享库中查找函数
错误:找不到函数。
/home/serg/libtest/app/lib shared.so:未定义的符号:在共享库中的函数_
这是有意义的,因为我也看不到使用nm的_shared_lib()中的函数_,这意味着我可能在步骤2中错误地构建了共享库。
如何在第二步修复我的命令,以便正确导出共享库中的函数_?
如果你注意到我在做一些奇怪的事情,也可以给我其他的建议。我还是个初学者。