匯出函式__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);