2014-09-05 7 views
2

我有一個C程序使用兩個libraries libA和libB。問題是;這兩個庫都有一個編譯器錯誤的list_delete函數。通過編寫這些代碼,我可以成功地編譯和鏈接我的代碼。如何讓庫使用其內部函數以防其他庫中存在相同的函數

#undef list_delete 
#define list_delete mysql_list_delete 

之後,我可以在我的代碼中調用libA的list_delete函數。但是當我調用libB內部調用list_delete函數的libB的list_delete函數的任何函數(而不是list_delete)時。

爲什麼? libB應該在內部調用list_delete函數而不是libA的list_function。

的問題是我怎麼能告訴libB庫使用它自己的list_delete功能(記住我的程序正在使用力霸的list_delete功能)

+0

您的庫是靜態還是動態的(.dll,.so,.dylib)?一種方法是將libB的'list_delete'聲明爲'static'。這將需要使用它的函數位於相同的編譯單元中,因爲它的符號不會被導出。 – jweyrich 2014-09-05 18:06:28

+0

圖書館是如此。我沒有控制庫,因爲這些是第三方庫 – 2014-09-05 18:15:02

回答

0

使用帶有RTLD_DEEPBIND的dlopen加載庫解決了這個問題。

dlopen(「libB」,RTLD_LAZY | RTLD_DEEPBIND);

RTLD_DEEPBIND (since glibc 2.3.4) Place the lookup scope of the symbols in this library ahead of the global scope. This means that a self-contained library will use its own symbols in preference to global symbols with the same name contained in libraries that have already been loaded. This flag is not specified in POSIX.1-2001.

0

如果這兩個庫鏈接到靜態就會發生這種情況。鏈接器在這兩個obj文件中都會看到一個list_delete符號,並且必須選擇最終可執行文件中的哪一個結束。

爲了避免這種情況,你需要:

  1. 重寫和重新編譯一個或兩個庫爲各自list_delete()功能使用不同的名稱。

  2. 更改您的應用程序以動態而非靜態地鏈接到庫,然後他們無法看到彼此的功能,不會再發生衝突。

+0

我不是這兩個庫的所有者,所以更改函數名稱是不可能的。我將我的代碼staticaly與libA鏈接起來,並與libB動態鏈接。 – 2014-09-05 18:05:37

+1

如果libB是動態鏈接的,它是一個外部模塊,因此不能調用靜態鏈接到應用程序中的libA函數,除非libB本身在內部使用libA,在這種情況下,它將使用自己的libA副本,而不是副本由您的應用使用。 – 2014-09-05 18:34:56

+0

這是我的理解,但libB調用libA函數。它只發生在Linux(Ubuntu,gcc)上。相同的代碼在OSX上工作正常 – 2014-09-05 18:40:19

相關問題