1. 程式人生 > >匯出函式__declspec(dllexport)

匯出函式__declspec(dllexport)

關於DLL的函式:

動態連結庫中定義有兩種函式:匯出函式(export function)和內部函式(internal function)。
匯出函式可以被其它模組呼叫,內部函式在定義它們的DLL程式內部使用。

輸出函式的方法有以下幾種:

1、傳統的方法

在模組定義檔案的EXPORT部分指定要輸入的函式或者變數。語法格式如下:

entryname[=internalname]   [@ordinal[NONAME]]   [DATA]   [PRIVATE] 

其中:

entryname是輸出的函式或者資料被引用的名稱;

internalname同entryname;

@ordinal表示在輸出表中的順序號(index);

NONAME僅僅在按順序號輸出時被使用(不使用entryname);

DATA表示輸出的是資料項,使用DLL輸出資料的程式必須宣告該資料項為_declspec(dllimport)。

上述各項中,只有entryname項是必須的,其他可以省略。

對於“C”函式來說,entryname可以等同於函式名;但是對“C++”函式(成員函式、非成員函式) 來說,entryname是修飾名。可以從.map映像檔案中得到要輸出函式的修飾

名,或者使用 DUMPBIN /SYMBOLS得到,然後把它們寫在.def檔案的輸出模組。DUMPBIN是VC提供的一個工具。

如果要輸出一個“C++”類,則把要輸出的資料和成員的修飾名都寫入.def模組定義檔案。

2、在命令列輸出

對連結程式LINK指定/EXPORT命令列引數,輸出有關函式。

3、使用MFC提供的修飾符號_declspec(dllexport)

在要輸出的函式、類、資料的宣告前加上_declspec(dllexport)的修飾符,表示輸出。__declspec (dllexport)在C呼叫約定、C編譯情況下可以去掉輸出函式名的下劃線字首。

extern "C "使得在C++中 使用C編譯方式成為可能。在“C++”下定義“C”函式,需要加extern “C”關鍵詞。用extern "C "來 指明該函式使用C編譯方式。輸出的“C”函式可

以從“C”程式碼裡呼叫。

例如,BaseFunce 工程中 的一個C++檔案有如下類:

#ifdef  _BASEFUNC_EXPORT_
#define  BASE_API   __declspec(dllexport)
#else
#define  BASE_API   __declspec(dllimport)
#endif

class BASE_API  CJCJMsgCmd_PrintRoadMap : public CJCJMsgCmd  
{
public:

 CJCJMsgCmd_PrintRoadMap();

 virtual ~CJCJMsgCmd_PrintRoadMap();

 virtual void Execute();

}

在另外工程中 CDlgJCJModule類中 需要將 CJCJMsgCmd_PrintRoadMap類中的 函式連結到 CDlgJCJModule 的C++ 可執行檔案中,在CDlgJCJModule的CPP檔案頭部加上“#include “…\BaseFunc\JCJMsgCmd_QueryXQ.h””

匯出 C 函式以用於 C 或 C++ 語言可執行檔案
如果在用 C 編寫的 DLL 中有希望從 C 語言或 C++ 語言模組訪問的函式,則應使用 __cplusplus 前處理器巨集確定正在編譯的語言,然後,如果是從 C++ 語言模組使用,則用 C 連結宣告這些函式。如果使用此技術併為 DLL 提供標頭檔案,則這些函式可以原封不動地由 C 和 C++ 使用者使用。
可由 C 和 C++ 客戶端應用程式使用的標頭檔案:

// MyCFuncs.h
#ifdef __cplusplus
extern "C" {  // only need to export C interface if
              // used by C++ source code
#endif

__declspec( dllimport ) void MyCFunc();
__declspec( dllimport ) void AnotherCFunc();

#ifdef __cplusplus
}
#endif

如果需要將 C 函式連結到 C++ 可執行檔案,並且函式宣告標頭檔案沒有使用上面的技術,則在 C++ 原始檔中新增下列內容以防止編譯器修飾 C 函式名:

extern "C" {
#include "MyCHeader.h"
}

匯出 C++ 函式以用於 C 語言可執行檔案
如果在用 C++ 編寫的 DLL 中有希望從 C 語言模組訪問的函式,應使用 C 連結而不是 C++ 連結來宣告這些函式。除非另外指定,C++ 編譯器使用 C++ 型別安全命名約定(也稱作名稱修飾)和 C++ 呼叫約定(使用此呼叫約定從 C 呼叫會很困難)。

若要指定 C 連結,請為函式宣告指定 extern “C”。例如:

extern "C" __declspec( dllexport ) int MyFunc(long parm1);