2010-05-26 82 views
2

我在C中創建共享庫,但不知道源代碼的正確實現是什麼。C中的共享庫

我想創建例如像一個API,printHello,

int printHello(char * text); 

這printHello功能調用另一個功能:

在源文件中,libprinthello.c,

void printHello(char * text) 
{ 
    printHi(); 
    printf("%s", text); 
} 

由於此printHello功能是用戶或應用程序的界面:

在頭文件libprinthello.h,

extern void printHello(char * text); 
的printHi功能的源文件中

然後,printhi.c

void printHi() 
{ 
    printf("Hi\n"); 
} 

然後我的問題是,因爲printHello是我想的唯一功能在用戶中暴露,我應該在printHi函數中做什麼實現?

我是否還應該在extern中聲明printHi函數?

+0

你應該提到的環境。在我的迴應中,我提出了一個既適用於Windows環境又適用於Unix環境的解決方案。 – INS 2010-05-26 08:21:31

回答

1

理想情況下,如果您不希望用戶致電printHi()函數,那麼它們應該對他們不可見。如果這不可行,則使用約定來指示哪些名稱將被用戶調用,哪些不是。通常情況下,這是通過領先的下劃線完成的,但這可能會導致各種衝突。因此,如果您的庫有一個命名約定,那麼可以使用pfx_GlobalName()來記錄用戶可調用的函數,pfxInternalName()可以使用無證函數,反之亦然,或者使用一些相似的約定。然後,您可以簡單地告訴用戶,不支持直接調用未記錄的函數,並且任何對它們的使用在將來的版本中都可能會中斷(或者可能會重命名該函數或其他函數)。偶爾做出更改以明確你的意思是說你的意思。

因此,如果隱藏的函數可以放入與已記錄的公共函數相同的源模塊中,請將它們隱藏起來。如果您不能,請使用命名約定來指示隱藏的功能不適合最終用戶使用。

您可以使用GCC控制符號映射和事物符號的可見性;雖然這很煩瑣。

+0

你也可以通過使它們成爲靜態函數來使它不可見,它不像屬性那樣編譯器特定,但是強制代碼上的某個結構。 – Hasturkun 2010-05-26 09:15:29

5

您可以使用兩個獨立的頭文件:

libprinthello.h

#ifndef LIBPRINTHELLO_H /* These are include guards */ 
#define LIBPRINTHELLO_H 

void printHello(char * text); 

#endif 

libprinthi.h

#ifndef LIBPRINTHI_H 
#define LIBPRINTHI_H 

void printHi(); 

#endif 

libprinthello.c

#include "libprinthi.h" 
#include "libprinthello.h" 

void printHello(char * text) 
{ 
    printHi(); 
    printf("%s", text); 
} 

libprinthi.c

#include "libprinthi.h" 

void printHi()  
{  
    printf("Hi\n");  
}  

然後用戶代碼只包含libprinthello.h,並從用戶保持libprinthi.h遠,使得printHi()看不見他們(用戶代碼也將連接對共享庫):

#include "libprinthello.h" 

int main() 
{ 
    printHello("Hello World!\n"); 
    return 0; 
} 
3

如果你把printHi的定義libprinthello.c, 你可以簡單地把它聲明靜態的,它只會 是在同一 文件中定義的其他功能進行訪問。如果您想將自定義翻譯單元中的定義放入其 中,則不會有可移植的方式將 隱藏給庫的用戶,但您可以使用 將它隱藏在實現特定的方式中。例如,對於 示例,使用gcc可以使用 _ _屬性_ _((visibility(「hidden」)))。 但是,簡單地將聲明從 中刪除,公共頭文件應該足以使 庫的用戶不使用該函數。

1

考慮這個文件(Export_Macro.h)

#ifndef EXPORT_MACRO_H 
#define EXPORT_MACRO_H 

#ifdef _WINDOWS 
    #ifdef I_WANT_TO_EXPORT_MACROS 
     #define EXPORT_MACRO __declspec(dllexport) 
    #else 
     #define EXPORT_MACRO __declspec(dllimport) 
    #endif 
#else 
    #define EXPORT_MACRO 
#endif 

#endif // EXPORT_MACRO_H 

在源代碼中做到這一點:

#include "Export_Macro.h" 
... 
// for functions you want to export outside the DLL (Dynamic Link Library)/so (Shared Object) 
EXPORT_MACRO void printHello(char * text); 

這個工作對我來說相當不錯。

更完整的解釋和導出宏,你可以找到here

後來編輯:這應該在Unix和Windows中工作,沒有任何大問題。

+0

你提供的鏈接是用於C++的,是C中的行爲是否相同? – rzetterberg 2011-10-26 08:45:01

+1

只要你使用'extern「C」'作爲從C++導出的函數,但是從C調用的函數就不會有任何問題。如果你只使用C'extern「C」'是可選的。 – INS 2011-10-27 14:09:23

+0

感謝您的回答。 Upvoted – rzetterberg 2011-10-28 07:58:45