2010-12-17 142 views
4

我在我的「C」代碼中有一些功能。當我編譯.so時,我在結果.so文件中看到所有名稱。我如何指定(在代碼或make文件中)只有一些函數應該被導出,而其他函數是專用於內部使用的。如何在編譯C代碼時指定從.so庫導出哪些函數?

+0

我認爲.def文件可用於此目的。 – ruslik 2010-12-17 00:32:50

+0

@ruslik即窗口 – alternative 2010-12-17 00:47:31

回答

7

在C語言中,如果你想讓一個函數保持在文件內部(技術上說是「編譯單元」),那麼你就聲明它是「靜態的」。例如,

static int privateAddOne(int x) { return x + 1; } 
+2

私有的編譯單元和私有的庫幾乎是不一樣的 - 大多數不平凡的庫有許多源文件。 – 2010-12-17 07:44:33

17

既然你提到.so文件,好像你正在使用gcc或GCC-一樣編譯一個合理的假設。

默認情況下,所有extern函數在鏈接對象中都可見。您可以隱藏使用hidden屬性上的案件逐案基礎功能(和全局變量)(同時保持它們extern,這使得他們能夠從其他源文件在同一個庫中使用):

int __attribute__((visibility("hidden"))) foo(void) 
{ 
    return 10; 
} 

或者,您可以在編譯時將-fvisibility=hidden選項傳遞給gcc,將缺省值更改爲hidden。然後,您可以使用以下標記特定函數進行導出:

__attribute__((visibility("default"))) 
+1

+1老實說,這是比接受的更好的答案(因爲它更強大)。當然,你應該使用這兩種混合! – alternative 2010-12-17 00:48:39

+0

+1要添加另一個選項,您可以使用ld鏈接器和版本腳本的組合來實現類似的結果,而無需觸摸源代碼。 – vanza 2010-12-17 00:57:32

+0

這個答案是正確的,但你永遠不要使用它。依靠隱藏符號來隱藏符號以避免污染名稱空間並破壞調用程序的代碼本質上是不可移植的。如果您需要不應該在庫本身之外使用的外部函數,則應該簡單地將它們的名稱加上一些庫特定的垃圾(但不包括前導下劃線)。 – 2010-12-17 03:45:24