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 */