動態庫編譯:.so: undefined symbol
阿新 • • 發佈:2019-01-26
這幾天學習了下共享庫相關知識,今天編碼發現一點小問題(雖然是小問題,也花了幾個小時查詢),這裡記錄下,給大家作個參考。
1、問題描述
g++編譯庫檔案,編譯的時候不報錯,但是執行主程式的時候會出現以下錯誤:
/opt/code/c++/sharelib/libshare.so: undefined symbol: my_print
2、解決方案
編譯共享庫的時候,一定要以C的方式進行編譯。
純C程式碼,可直接用gcc編譯;
C++程式碼,需將對外暴露的介面(即外部可以直接呼叫的介面)以C方式編譯,即使用extern "C" { 程式碼 }
。
3、程式碼例項
共享庫 sharelib.cpp:
編譯:g++ -o libshare.so -fPIC -Wall -shared sharelib.cpp
include <stdio.h>
#include <iostream>
extern "C" //“my_print”是該共享庫提供的對外介面,所以需要以C方式編譯
{
int my_print()
{
std::cout << "hello world" << std::endl;
return 0;
}
}
主程式 test_sharelib.cpp:
編譯:g++ -o test_sharelib -Wl,--rpath,/opt/code/c++/sharelib test_sharelib.cpp -ldl
“/opt/code/c++/sharelib” 是共享庫所在目錄
#include <stdio.h>
#include <iostream>
#include <dlfcn.h>
int main()
{
void* handle = NULL;
char* error;
int (*p)();
handle = dlopen("libshare.so", RTLD_LAZY);
if (NULL == handle)
{
if ((error = dlerror()) != NULL )
{
std::cout << error << std::endl;
return -1;
}
}
p = (int(*)())dlsym(handle, "my_print"); //這裡查詢“my_print”,所以上面的my_print函式需要以C方式編譯
if ((error = dlerror()) != NULL)
{
std::cout << error << std::endl;
return -1;
}
p();
dlclose(handle);
return 0;
}