2012-07-30 20 views
0

我有一個奇怪的問題。兩個項目鏈接相同的SQLite庫靜態導致問題

我正在使用C編寫的共享庫和一個用C++編寫的GUI應用程序。 GUI應用程序使用共享庫。這個共享庫使用SQLite合併和靜態鏈接。 GUI也用於某些配置目的的SQLite。它也是靜態鏈接的。他們兩人都使用最新的SQLite版本。

我的共享書庫使用FTS4。通過在編譯共享庫時提供編譯時選項來啓用FTS4。所有這些與共享庫一起運行良好。我在共享庫代碼庫中的所有測試都通過了。

當我在GUI程序中開始使用它時,會發生問題。我遇到錯誤,如Unknown module FTS4。這很奇怪,因爲我在共享庫中靜態鏈接了它,並且所有此GUI程序都會動態鏈接到我的庫。當我將FTS編譯選項設置爲GUI程序時,錯誤消失並且一切正常。

總之,

libfoo.so - 靜態鏈接的SQLite與FTS4選項開啓 foo - 有任何特殊的編譯時間選項靜態鏈接的SQLite。動態鏈接到libfoo

我不知道爲什麼會發生這種情況。任何幫助將是偉大的!

+0

沒有編譯/鏈接器錯誤。它在運行時加載不正確的函數版本。它總是從'foo'加載SQLIte函數。 – 2012-07-30 06:42:33

回答

1

聽起來像共享庫中的所有sqlite函數都被導出。因此,當您加載共享對象時,所有這些函數都會被解析到主應用程序,該應用程序還定義了符號名稱的相同副本,但具有不同的功能。

你可能有更好的運氣編譯共享對象與映射文件看起來像:

{ 
global: 
    *; 
local: 
    sqlite3*; 
}; 

把它放到一個名爲foo.map文件和鏈接libfoo.so

gcc -Wl,--version-script=foo.map -o libfoo.so <dependent files> 
(使用gcc假設)

這應該有希望導致在.so內使用內部符號,而不是在主應用程序中定義的內部符號。

+0

謝謝。這就說得通了。我會試一試。所以我認爲這不會發生在MSVC上。因爲MSVC不會導出所有的功能。 – 2012-07-30 09:12:12

+0

默認情況下,Windows不會從dll中導出符號 - 您必須明確地導出您想要提供的每個符號;另外窗口鏈接符號到庫名稱 – Petesh 2012-07-30 09:17:45