1. 程式人生 > >動態庫編譯:.so: undefined symbol

動態庫編譯:.so: undefined symbol

這幾天學習了下共享庫相關知識,今天編碼發現一點小問題(雖然是小問題,也花了幾個小時查詢),這裡記錄下,給大家作個參考。

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; }