龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > C/C++开发 >

在Visual Studio中用C++语言创建DLL动态链接库图文教程(2)

时间:2014-10-01 02:28来源:网络整理 作者:网络 点击:
分享到:
复制代码 代码如下: #include windows.h #include iostream using namespace std; typedef int (*AddFunc)(int a, int b); int main(int argc, char *argv[]) { HMODULE hDll = LoadLibrary("DLLDemo1.dll")

复制代码 代码如下:

#include <windows.h>
#include <iostream>
using namespace std;
typedef int (*AddFunc)(int a, int b);
int main(int argc, char *argv[])
{
      HMODULE hDll = LoadLibrary("DLLDemo1.dll");
      if (hDll != NULL)
      {
            AddFunc add = (AddFunc)GetProcAddress(hDll, "Add");
            if (add != NULL)
            {
                  cout<<add(2, 3)<<endl;
            }
            FreeLibrary(hDll);
      }
}

上述代码都在DLLDemo1工程中。(工程下载)。

DllMain函数

Windows在加载DLL时,需要一个入口函数,就像控制台程序需要main函数一样。有的时候,DLL并没有提供DllMain函数,应用程序也能成功引用DLL,这是因为Windows在找不到DllMain的时候,系统会从其它运行库中引入一个不做任何操作的默认DllMain函数版本,并不意味着DLL可以抛弃DllMain函数。

根据编写规范,Windows必须查找并执行DLL里的DllMain函数作为加载DLL的依据,它使得DLL得以保留在内存里。这个函数并不属于导出函数,而是DLL的内部函数,这就说明不能在客户端直接调用DllMain函数,DllMain函数是自动被调用的。

DllMain函数在DLL被加载和卸载时被调用,在单个线程启动和终止时,DllMain函数也被调用。参数ul_reason_for_call指明了调用DllMain的原因,有以下四种情况:

DLL_PROCESS_ATTACH:当一个DLL被首次载入进程地址空间时,系统会调用该DLL的DllMain函数,传递的ul_reason_for_call参数值为DLL_PROCESS_ATTACH。这种情况只有首次映射DLL时才发生;

DLL_THREAD_ATTACH:该通知告诉所有的DLL执行线程的初始化。当进程创建一个新的线程时,系统会查看进程地址空间中所有的DLL文件映射,之后用DLL_THREAD_ATTACH来调用DLL中的DllMain函数。要注意的是,系统不会为进程的主线程使用值DLL_THREAD_ATTACH来调用DLL中的DllMain函数;

DLL_PROCESS_DETACH:当DLL从进程的地址空间解除映射时,参数ul_reason_for_call参数值为DLL_PROCESS_DETACH。当DLL处理DLL_PROCESS_DETACH时,DLL应该处理与进程相关的清理操作。如果进程的终结是因为系统中有某个线程调用了TerminateProcess来终结的,那么系统就不会用DLL_PROCESS_DETACH来调用DLL中的DllMain函数来执行进程的清理工作。这样就会造成数据丢失;

DLL_THREAD_DETACH:该通知告诉所有的DLL执行线程的清理工作。注意的是如果线程的终结是使用TerminateThread来完成的,那么系统将不会使用值DLL_THREAD_DETACH来执行线程的清理工作,这也就是说可能会造成数据丢失,所以不要使用TerminateThread来终结线程。以上所有讲解在工程DLLMainDemo(工程下载)都有体现。

函数导出方式

在DLL的创建过程中,我使用的是_declspec( dllexport )方式导出函数的,其实还有另一种导出函数的方式,那就是使用导出文件(.def)。你可以在DLL工程中,添加一个Module-Definition File(.def)文件。.def文件为链接器提供了有关被链接器程序的导出、属性及其它方面的信息。

对于上面的例子,.def可以是这样的:

复制代码 代码如下:

LIBRARY     "DLLDemo2"
EXPORTS
Add @ 1 ;Export the Add function

Module-Definition File(.def)文件的格式如下:

精彩图集

赞助商链接