已解決。請參閱下面的更正(標記爲FIXED)。使用gcc構建共享庫
我在使用gcc創建共享庫時遇到了問題。
我創建了一個小樣本項目,它與我正在處理的實際項目的結構非常接近。我做了它可以作爲一個tar.gz檔案位置:
http://209.59.216.197/libtest.tar.gz
固定:我已經提供了固定的版本在這裏:
http://209.59.216.197/libtest_fixed.tar.gz
在此示例項目,我有一個應用程序(app)加載我在運行時編寫的共享庫(libshared.so),並調用共享庫定義的函數:function_inside_shared_lib()。
反過來,此共享庫使用靜態庫(libstatic.a)中定義的函數:function_inside_static_lib()。
問題是當我構建共享庫時,符號「function_inside_shared_lib」不能被導出。我使用「nm」檢查了共享庫,但符號不存在。我想知道如果我使用創建的共享庫的命令是正確的:
g++ -g -ggdb -fPIC -rdynamic -I ../static -c shared.cpp -o shared.o
g++ -g -ggdb -fPIC -rdynamic -shared -L ../static -lstatic -o libshared.so
FIXED:正確的命令是:
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 -lstatic
我試圖與不-rdynamic這些命令,以及帶和不帶-fPIC。結果總是一樣的。
我使用Ubuntu 10.04(64位)與g ++版本4.4.3。
下面是完整的示例項目。 (或者您可以使用我的文章頂部的鏈接下載該檔案)。
[email protected]:~/libtest$ ls
app shared static
這裏有三個組成部分:
組分1:定義一個函數調用function_inside_static_lib()靜態庫。
這包括以下的:
[email protected]:~/libtest$ cd static/ [email protected]:~/libtest/static$ ls static.cpp static.h
static.h
// Header file for the static library
int function_inside_static_lib(int arg1, int arg2);
static.cpp
// 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:使用靜態庫並定義新功能的共享庫。
[email protected]:~/libtest$ cd shared
[email protected]:~/libtest/shared$ ls
shared.cpp
shared.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:使用共享庫中的應用。
[email protected]:~/libtest$ cd app
[email protected]:~/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;
}
這裏是我用來構建所有的命令se組件。請注意,我希望調試符號在最終生成的應用程序中可用。理想情況下,我希望能夠在應用程序內部進行回溯,並查看共享庫和靜態庫中的符號。
1:構建靜態庫。我覺得我很好用此步驟:
[email protected]:~/libtest/static$ g++ -g -ggdb -c static.cpp -o static.o # See the FIXED version just below
[email protected]:~/libtest/static$ ar rcs libstatic.a static.o
[email protected]:~/libtest/static$ ls
libstatic.a static.cpp static.h static.o
固定:上面的第一個命令必須包含-fPIC爲好。正確的命令是
g++ -g -ggdb -fPIC -c static.cpp -o static.o
2:構建共享庫。我很確定這是我出錯的地方。
[email protected]:~/libtest/shared$ g++ -g -ggdb -fPIC -rdynamic -I ../static -c shared.cpp -o shared.o
[email protected]:~/libtest/shared$ g++ -g -ggdb -fPIC -rdynamic -shared -L ../static -lstatic -o libshared.so # See just below for FIXED version [email protected]:~/libtest/shared$ ls
libshared.so shared.cpp shared.o
FIXED:上述第二個命令應該是:
g++ -g -ggdb -fPIC -rdynamic -shared -L../static -o libshared.so shared.o -lstatic
此時,如果用完納米至檢查內部libshared.so符號,我沒有看到function_inside_shared_lib()在任何地方,即使使用nm的-a和-D選項。 (但是,我確實在shared.o中看到它)。
編輯:與上面的修復程序,該符號顯示爲_Z26function_inside_shared_libii
。
3:構建應用程序:
首先,共享庫複製到應用程序文件夾:
[email protected]:~/libtest$ cp shared/libshared.so app/
[email protected]:~/libtest$ cd app
[email protected]:~/libtest/app$ ls
app.cpp libshared.so
現在編譯:
[email protected]:~/libtest/app$ g++ -g -ggdb -ldl -L. -lshared app.cpp -o app
[email protected]:~/libtest/app$ ls
app app.cpp libshared.so
如果我嘗試運行:
[email protected]:~/libtest/app$ ./app
app: loading the shared library.
app: Looking for function_inside_shared_lib
Error: Could not find the function.
/home/serg/libtest/app/libshared.so: undefined symbol: function_inside_shared_lib
這很有道理,因爲我看不到使用nm的function_inside_shared_lib(),這意味着我可能在第2步中錯誤地構建了共享庫。
如何在第二步修復我的命令以便function_inside_shared_lib正確導出?
如果你發現我做了什麼奇怪的事情,還可以給我任何其他建議。我還是個初學者。
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries。html – Anycorn 2010-08-27 22:27:44
構建共享對象庫的命令看起來不正確 - 它沒有提到shared.o。你輸入的內容是否正確? – Beta 2010-08-27 23:08:43
這是一個問題還是十七個問題或十七個答案?我不能告訴任何更多... – 2012-12-27 22:05:32