我正在为一个嵌入式系统交叉编译一个程序。程序使用一个共享库,我这样打开它。

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>      //needed for dynamic linking

void  *FunctionLib;     //Handle to shared lib file
int   (*Function)();    //Pointer to loaded routine
const char *dlError;    //Pointer to error string

int main( argc, argv )
{
    int   rc;               //return codes
    printf("start...\n");

    //Open Dynamic Loadable Libary with absolute path
    FunctionLib = dlopen("/lalabu/sharedLib.so",RTLD_LAZY | RTLD_GLOBAL);
    dlError = dlerror();
    printf("Open sharedLib.so returns: %s \n", dlError);
    if( dlError ) exit(1);

    //Find function
    Function = dlsym( FunctionLib, "getSomething");
    dlError = dlerror();
    printf("Find symbol getSomething returns: %s \n", dlError);
    if( dlError ) exit(1);
...

我正在用以下命令编译代码
mips-linux-uclibc-gcc -Wall -ldl ./dynamic_linking.c -o /dynamic_linking

它可以在没有任何警告的情况下工作。
如果现在尝试在我的设备上执行此代码,则会出现以下错误:
# ./dynamic_linking
start...
Open sharedLib.so returns: (null)
Find symbol getSomething returns: Unable to resolve symbol
./dynamic_linking: can't resolv '_ZNSt8ios_base4InitD1Ev'

如果我和IDA一起看一下sharedLib.so想要导入哪些函数,就会看到函数(或符号?)_ZNSt8ios_base4InitD1Ev'和它应该在哪里(libc.so.0)。
如果我再看看libc.so.0,还有IDA,我看不到像这样调用的函数。也没有什么像ios_base,ios或base。
我已经用dlopen()尝试了各种标志组合,结果总是出现上述错误,除了现在使用RTLD_而不是RTLD_LAZY时
Segmentation fault (core dumped)

而不是
./dynamic_linking: can't resolv '_ZNSt8ios_base4InitD1Ev'

此外,我尝试了一些gcc链接选项,比如rdynamic,结果总是一样的。
此外,我尝试使用一个不使用'ZNSt8ios_base4InitD1Ev,libc.so.0'的共享库来检查我的c代码是否工作。我只更改了名称和绝对路径,删除了find函数部分。它工作正常。
正如你可能从我的文章中认识到的,我刚刚开始交叉编译和使用动态库,所以也许我的错在别的地方。此外,我不知道我是否知道问题在哪里,所以欢迎任何提示。如果你需要更多的信息,我很乐意给你。
你好,平谷

最佳答案

_ZNSt8ios-base4InitD1Ev不是C符号,而是C++符号。

$ echo _ZNSt8ios-base4InitD1Ev | c++filt

不提供任何线索,但如果您将-替换为_(可能是打字错误?):
$ echo _ZNSt8ios_base4InitD1Ev | c++filt
std::ios_base::Init::~Init()

这就是C++ STD库内部类的析构函数。所以你应该检查libstdc++.so库而不是libc.so
我的建议是用G++编译你的程序,这样C++库就被正确初始化了。它不打算动态加载,这就是分割错误的原因。

07-28 03:06
查看更多