dllimport/dllexport 的规则和限制
Microsoft 专用
如果你没有使用
dllimport
或dllexport
特性声明函数,则此函数被视为不是 DLL 接口的一部分。 因此,函数的定义必须存在于该模块或同一程序的另一个模块中。 若要使函数成为 DLL 接口的一部分,您必须将其他模块中函数的定义声明为dllexport
。 否则,在构建客户端时,将生成链接器错误。如果程序中的单个模块包含对同一函数的
dllimport
和dllexport
声明,则dllexport
特性优先于dllimport
特性。 但是,会生成编译器警告。 例如:#define DllImport __declspec( dllimport ) #define DllExport __declspec( dllexport ) DllImport void func1( void ); DllExport void func1( void ); /* Warning; dllexport */ /* takes precedence. */
无法利用使用
dllimport
特性声明的数据对象的地址来初始化静态数据指针。 例如,下面的代码将生成错误:#define DllImport __declspec( dllimport ) #define DllExport __declspec( dllexport ) DllImport int i; . . . int *pi = &i; /* Error */ void func2() { static int *pi = &i; /* Error */ }
如果利用使用
dllimport
声明的函数的地址来初始化静态函数指针,会将指针设置为 DLL 导入 thunk(将控制权转移给函数的代码存根)的地址,而不是函数的地址。 此赋值不生成错误消息:#define DllImport __declspec( dllimport ) #define DllExport __declspec( dllexport ) DllImport void func1( void . . . static void ( *pf )( void ) = &func1; /* No Error */ void func2() { static void ( *pf )( void ) = &func1; /* No Error */ }
由于包含对象声明中的
dllexport
特性的程序必须为该对象提供定义,因此您可以利用dllexport
函数的地址初始化全局或局部静态函数指针。 同样,您可以利用dllexport
数据对象的地址初始化全局或局部静态数据指针。 例如:#define DllImport __declspec( dllimport ) #define DllExport __declspec( dllexport ) DllImport void func1( void ); DllImport int i; DllExport void func1( void ); DllExport int i; . . . int *pi = &i; /* Okay */ static void ( *pf )( void ) = &func1; /* Okay */ void func2() { static int *pi = i; /* Okay */ static void ( *pf )( void ) = &func1; /* Okay */ }
结束 Microsoft 专用
请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈