dllimport, dllexport Microsoft Specific __declspec( dllimport ) declarator__declspec( dllexport ) declaratorThe dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages. They enable you to export and import functions, data, and objects to and from a DLL. These attributes explicitly define the DLL’s interface to its client, which can be the executable file or another DLL. Declaring functions as dllexport eliminates the need for a module-definition (.DEF) file, at least with respect to the specification of exported functions. Note that dllexport replaces the __export keyword.The declaration of dllexport and dllimport uses extended attribute syntax.Example// Example of the dllimport and dllexport class attributes __declspec( dllimport ) int i; __declspec( dllexport ) void func();extern "C" _declspec(dllexport) LRESULT KeyBoardProc(int nCode,WPARAM wParam,LPARAM lParam) { if(nCode==HC_ACTION) { } return 0;}
Microsoft Specific __declspec( dllimport ) declarator__declspec( dllexport ) declaratorThe dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages. They enable you to export and import functions, data, and objects to and from a DLL. These attributes explicitly define the DLL’s interface to its client, which can be the executable file or another DLL. Declaring functions as dllexport eliminates the need for a module-definition (.DEF) file, at least with respect to the specification of exported functions. Note that dllexport replaces the __export keyword.The declaration of dllexport and dllimport uses extended attribute syntax.Example// Example of the dllimport and dllexport class attributes
__declspec( dllimport ) int i;
__declspec( dllexport ) void func();extern "C" _declspec(dllexport) LRESULT KeyBoardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
if(nCode==HC_ACTION)
{
}
return 0;}
例如,在一个C++文件中,有如下函数:
extern "C" {void __declspec(dllexport) __cdecl Test(int var);}
其输出函数名为:Test
MFC提供了一些宏,就有这样的作用。AFX_CLASS_IMPORT:__declspec(dllexport)
AFX_API_IMPORT:__declspec(dllexport)
AFX_DATA_IMPORT:__declspec(dllexport)
AFX_CLASS_EXPORT:__declspec(dllexport)
AFX_API_EXPORT:__declspec(dllexport)
AFX_DATA_EXPORT:__declspec(dllexport)
AFX_EXT_CLASS: #ifdef _AFXEXT
AFX_CLASS_EXPORT
#else
AFX_CLASS_IMPORT
AFX_EXT_API:#ifdef _AFXEXT
AFX_API_EXPORT
#else
AFX_API_IMPORT
AFX_EXT_DATA:#ifdef _AFXEXT
AFX_DATA_EXPORT
#else
AFX_DATA_IMPORT 像AFX_EXT_CLASS这样的宏,如果用于DLL应用程序的实现中,则表示输出(因为_AFX_EXT被定义,通常是在编译器的标识参数中指定该选项/D_AFX_EXT);如果用于使用DLL的应用程序中,则表示输入(_AFX_EXT没有定义)。 要输出整个的类,对类使用_declspec(_dllexpot);要输出类的成员函数,则对该函数使用_declspec(_dllexport)。如:class AFX_EXT_CLASS CTextDoc : public CDocument
{
…
}extern "C" AFX_EXT_API void WINAPI InitMYDLL(); 这几种方法中,最好采用第三种,方便好用;其次是第一种,如果按顺序号输出,调用效率会高些;最次是第二种。
是否可告诉我 AFX_API_EXPORT 在那可以找到.
int add(int x,int y)
{
return x+y;
}
extern "C" _declspec (dllexport) int add3(int x,int y,int z)
{
return add(x,y)+z;
}
使用微软专用的_declspec (dllexport):(如上面的例子)
cpp文件在编译为OBJ文件时要对函数进行重新命名,C语言会把函数name重新命名为_name,而C++会重新命名为_name@@decoration,
extern "C"表示用C语言的格式将函数重命名
访问动态链接库:
静态调用
 用_declspec (dllexport)导出函数的DLL
extern "C"_declspec (dllimport) int add3(int x,int y,int z);
int main()
{
func()
return 0;
}
编译器生成像下面的代码
call func1
连接器传入像下面的代码
call 0x4000000 ; 函数func的地址
如果func在DLL中,连接器就无法得到func的直接地址;在32位系统下,连接器将生成一个thunk包含func的调用地址
0x40000000: jmp DWORD PTR __imp_func
__imp_func事func在.exe导入函数表中的地址,这个地址传入连接器进行连接
这样生成的代码比较大而且速度慢;
而使用__declspec(dllimport) 则直接告诉连接器直接调用DLL中func的地址,不要使用thunk
__declspec(dllimport) void func(void);
void main(void)
{
func1();
}
生成如下代码
call DWORD PTR __imp_func
这样的代码比使用thunk代码小而且要快