动态连接库
在Win32环境下开发动态连接库(dlls)是不能简单的等同于Windows 3.x的。这是初始化和终止例程的区别:他们调用的频繁程度,传输的什么,和有多少代码必须用汇编语言编写。
‘在Win32 dll中,初始化和终止使用同样的一个函数句柄。在Windows 3.x中,必须提供初始化函数,并且如果提供了终止函数必须命名为WEP。
‘Win32初始化函数是一个新进程在任意时间或者一个附加线程第一次调用该DLL,并且当一个进程或线程终止时调用。而在Windows 3.x中,初始化和终止函数在DLL的生命期中仅能调用一次。
‘在Win32中,可以用c语言编写整个DLL(就像一个其他处理器的接口帮助推荐的那样)。在Windows 3.x中,链接成一个目标文件的启动代码是用汇编语言编写的。一个目标文件中的微软c/c++链接,LIBENTRY.OBJ,存取寄存器中信息和叫做LibMain的c代码的信息。在win32中,你不需要这个文件。
在Win32中,DLL初始化函数和终止函数相同。根据协议这个函数命名为DllMain。一个DWORD(32比特)类型的参数,dwReason,通知函数是初始化还是终止,和进程还是和线程有关。当一个进程第一次访问一个DLL,初始化函数通过process-atach被调用:这是假定一个进程有一个线程。如果这个存取来自另外的线程,函数通过thread-attach被调用。无论如何,在Win32下有通知仅仅因为线程绑定和分离。
Win32 DLL初始化函数应该返回1表示成功。返回NULL表示失败。Windows 3.x DLL初始化函数是使用下面的信息:
‘DLL的实例句柄
‘DLL数据段
‘DLL'DEF文件指定的堆大小
‘命令行
win32 Dll使用以下信息:
‘hModule参数,模块句柄
‘dwReason参数,一个枚举类型,表示LibMain程序被调用的四个原因:进程绑定,线程绑定,进程断开,线程断开。
‘lpRrserved参数,没有使用
定义Win32初始化函数应该像下面的代码:
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved )
{
switch( dwReason) {
case DLL_PROCESS_ATTACH:
...
case DLL_THREAD_ATTACH:
...
case DLL_THREAD_DETACH:
...
case DLL_PROCESS_DETACH:
...
}
}
Win32模块句柄和Windows 3.x实例句柄有相同的用途。另外,Win32 DLL初始化函数不包括Windows 3.x的初始化参数。
DLL出口类
当你声明了一个类dllexport,它所有的成员函数和静态数据成员都被导出。你必须在同一个程序中提供所有这些成员的说明。另外,一个连接器错误产生。这个规则一个例外是纯虚函数。
译者注:声明一个dll函数的方法:
返回类型 APIENTRY 函数名(参数)
{……}
调用DLL函数
一旦你获得了dll函数的地址指针,你就可以用CallProcEx32W 或 CallProc32W从16位应用程序中调用他。你无法为 CallProc32W 创建一个原型,除非你做到了如下中的一点:
……
LoadLibraryEx函数
该函数将指定的可执行模块映射到调用进程的地址空间。可执行模块可以是.dll或.exe文件。该指定模块可能引起其他模块映射到这个地址空间。
HINSTANCE LoadLibraryEx(
LPCTSTR lpLibFileName, //可执行模块的名称
HANDLE hFile, // 保留,必须为NULL
DWORD dwFlags // 入口点执行标志
);
参数说明
lpLibFileName
指向以null结尾的字符串,表示Win32可执行模块的名字。这个名字特指文件名。
dwFlags
可能是DONT_RESOLVE_DLL_REFERENCES LOAD_LIBRARY_AS_DATAFILE LOAD_WITH_ALTERED_SEARCH_PATH
该死的blog,没什么好写的,烦死了。