2012-12-17 204 views
1

我正在交叉編譯嵌入式系統的程序。該程序使用共享庫,我打開這樣的。無法解析符號

#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_NOW代替RTLD_LAZY我得到

Segmentation fault (core dumped) 

代替

./dynamic_linking: can't resolv '_ZNSt8ios_base4InitD1Ev' 

此外我嘗試一個像rdynamic這樣的gcc鏈接選項很少,總是有相同的結果。
此外,我試圖使用共享庫,它不使用_ZNSt8ios_base4InitD1Ev,'libc.so.0'來檢查我的c代碼是否工作。我只改變了名稱和絕對路徑並刪除了查找功能部分。它工作沒有錯誤。
正如你從我的文章中可以看到的,我剛開始交叉編譯和使用動態庫,所以也許我的錯在別的地方。此外,我不確定我是否能夠理解問題所在,因此歡迎提供任何提示。如果您需要更多信息,我很樂意將它們提供給您。
問候,Pingu

回答

3

_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++庫被正確初始化。它不打算被動態加載,這就是分段故障的原因。

+0

感謝您的回答,我用mips-linux-uclibc-cpp -Wall ./dynamic_linking.c -o ./dynamic_linking編譯了程序,並且它編譯了沒有任何錯誤。我可以在明天檢查設備是否工作,我會給予反饋。而不是_確實是一個錯字,對不起。 – Pingu

+0

@Pingu:但要小心! ''cpp'不是GCC C++編譯器的名稱(即'g ++'或'C++'),它是C預編譯器的名稱,如果'dynamic_linking'程序最終成爲預編譯器的輸出! – rodrigo

+0

我沒有爲我的設備使用gcc C++編譯器,但閱讀這篇文章http:// stackoverflow。com/questions/6626363/why-use-g-instead-of-gcc-to-compile-cc-files我認爲使用C++ std庫可以用gcc編譯代碼。我會盡力弄清楚。 – Pingu