导出 DLL 函数
要导出 DLL 函数,您可以向导出的 DLL 函数中添加函数关键字,也可以创建模块定义文件 (.def) 以列出导出的 DLL 函数。
方法一、向导出的 DLL 函数中添加函数关键字
要使用函数关键字,您必须使用以下关键字来声明要导出的各个函数:
__declspec(dllexport)
要在应用程序中使用导出的 DLL 函数,您必须使用以下关键字来声明要导入的各个函数:
__declspec(dllimport)
通常情况下,您最好使用一个包含 define 语句和 ifdef 语句的头文件,以便分隔导出语句和导入语句。
方法二、创建模块定义文件 (.def) 以列出导出的 DLL 函数
使用模块定义文件来声明导出的 DLL 函数。当您使用模块定义文件时,您不必向导出的 DLL 函数中添加函数关键字。在模块定义文件中,您可以声明 DLL 的 LIBRARY 语句和 EXPORTS 语句。
关于特定情况下的调用,比如DLL函数中使用到了win32 API或者将C++生成的DLL供标准C语言使用,则需要注意以下一些情况:
如果使用到了win32 API,则应该使用调用方式为“__stdcall”。
在将C++生成的DLL供标准C语言使用,输出文件需要用“extern "C"”修饰,否则不能被标准C语言调用。如果使用“__stdcall”调用方式,可能产生C不识别的修饰名,所以设置导出函数时要采用.def文件形式,而不是__declspec(dllexport)形式。后者会进行修饰名转换,C语言无法识别函数。
下面的代码是一个定义文件的示例。
// SampleDLL.def
//
LIBRARY "sampleDLL"
EXPORTS
HelloWorld
示例 DLL 和应用程序
在 Microsoft Visual C++ 6.0 中,可以通过选择“Win32 动态链接库”项目类型或“MFC 应用程序向导 (dll)”来创建 DLL。
下面的代码是一个在 Visual C++ 中通过使用“Win32 动态链接库”项目类型创建的 DLL 的示例。
// SampleDLL.cpp
//
#include "stdafx.h"
#define EXPORTING_DLL
#include "sampleDLL.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
void HelloWorld()
{
MessageBox( NULL, TEXT("Hello World"), TEXT("In a DLL"), MB_OK);
}
// File: SampleDLL.h
//
#ifndef INDLL_H
#define INDLL_H
#ifdef EXPORTING_DLL
extern __declspec(dllexport) void HelloWorld() ;
#else
extern __declspec(dllimport) void HelloWorld() ;
#endif
#endif
下面的代码是一个“Win32 应用程序”项目的示例,该示例调用 SampleDLL DLL 中的导出 DLL 函数。
// SampleApp.cpp
//
#include "stdafx.h"
#include "sampleDLL.h"
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HelloWorld();
return 0;
}
注意:在加载时动态链接中,您必须链接在生成 SampleDLL 项目时创建的 SampleDLL.lib 导入库。
在运行时动态链接中,您应使用与以下代码类似的代码来调用 SampleDLL.dll 导出 DLL 函数。
...
typedef VOID (*DLLPROC) (LPTSTR);
...
HINSTANCE hinstDLL;
DLLPROC HelloWorld;
BOOL fFreeDLL;
hinstDLL = LoadLibrary("sampleDLL.dll");
if (hinstDLL != NULL)
{
HelloWorld = (DLLPROC) GetProcAddress(hinstDLL, "HelloWorld");
if (HelloWorld != NULL)
(HelloWorld);
fFreeDLL = FreeLibrary(hinstDLL);
}