zoukankan      html  css  js  c++  java
  • VC++ 动态DLL模板-DllMain函数

    1、VS2003新建DLL项目dllTest

    2、项目dllTest中添加脚本lib.h,代码如下:

    1 #ifndef LIB_H
    2 #define LIB_H
    3 extern "C" int add(int x,int y);
    4 extern "C" int mius(int x,int y);
    5 #endif 

    3、项目dllTest中添加脚本lib.cpp,代码如下:

     1 #include "lib.h"
     2 #include "windows.h"
     3 #include "stdio.h"
     4 
     5 //如果程序员没有为DLL模块编写一个DLLMain函数,系统会从其它运行库中引入一个不做任何操作的
     6 //缺省DLLMain函数版本。在单个线程启动和终止时,DLLMain函数也被调用。正如由dwReason参数所
     7 //表明的那样。
     8 BOOL APIENTRY DllMain( HANDLE hModule,    
     9 /*
    10     进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识进程自己还有一个HINSTANCE句柄。
    11 所有这些模块句柄都只有在特定的进程内部有效,它们代表了DLL或EXE模块在进程虚拟空间中的起始
    12 地址。在Win32中,HINSTANCE和HMODULE的值是相同的,这两种类型可以替换使用。进程模块句柄几乎
    13 总是等于0x400000,而DLL模块的加载地址的缺省句柄是0x10000000。如果程序同时使用了几个DLL模
    14 块,每一个都会有不同的HINSTANCE值。这是因为在创建DLL文件时指定了不同的基地址,或者是因为
    15 加载程序对DLL代码进行了重定位。 
    16 */
    17                         DWORD  ul_reason_for_call, 
    18                       LPVOID lpReserved
    19                       )
    20 {
    21     switch (ul_reason_for_call)
    22     {
    23     case DLL_PROCESS_ATTACH:
    24         printf("
    process attach of dll");
    25         break;
    26     case DLL_THREAD_ATTACH:
    27         printf("
    thread attach of dll");
    28         break;
    29     case DLL_THREAD_DETACH:
    30         printf("
    thread detach of dll");
    31         break;
    32     case DLL_PROCESS_DETACH:
    33         printf("
    process detach of dll");
    34         break;
    35     }
    36     return TRUE;
    37 }
    38 
    39 int add(int x,int y)
    40 {
    41     return x + y;
    42 }
    43 int mius(int x,int y)
    44 {
    45     return x - y;
    46 }

    4、项目dllTest中添加脚本lib.def,代码如下:

    1 LIBRARY LIB
    2 EXPORTS
    3 add @ 1
    4 mius @ 2

    5、build生成dllTest.dll文件

    6、添加检测项目dllCall

    7、添加主程序脚本dllCall.cpp,代码如下:

    特别说明:MAKEINTRESOURCE(1)等同def中定义的对应函数名称。

     1 #include "stdafx.h"
     2 #include "windows.h"
     3 
     4 typedef int (* lpAddFun)(int,int);
     5  
     6 int main(int argc, char* argv[])
     7 {
     8     HINSTANCE hDll; 
     9     lpAddFun addFun;
    10     hDll = LoadLibrary("..\Debug\dllTest.dll");
    11     if (hDll != NULL)
    12     {
    13     //    addFun = (lpAddFun)GetProcAddress(hDll,"add");    
    14         addFun = (lpAddFun)GetProcAddress(hDll,MAKEINTRESOURCE(1));
    15         //MAKEINTRESOURCE直接使用导出文件中的序号
    16         if(addFun!=NULL)
    17         {
    18             int result =  addFun(2,3);    
    19             printf("
    call add in dll:%d",result);
    20         }    
    21 
    22         addFun = (lpAddFun)GetProcAddress(hDll,MAKEINTRESOURCE(2));
    23         //MAKEINTRESOURCE直接使用导出文件中的序号
    24         if(addFun!=NULL)
    25         {
    26             int result =  addFun(2,3);    
    27             printf("
    call mius in dll:%d",result);
    28         }
    29         FreeLibrary(hDll);
    30     }    
    31     getchar();
    32       return 0;
    33 }

    8、Ctrl+F5调试运行结果如下:

    特别说明:这里看到的process attach和detach,若是在dll中有线程存在,且封装在接口add或mius中,则会在process attach后执行相应的thread attacth和detach。

  • 相关阅读:
    java web项目防止多用户重复登录解决方案
    java提高篇(二一)-----ArrayList
    转:为什么需要htons(), ntohl(), ntohs(),htons() 函数
    转:对于linux下system()函数的深度理解(整理)
    转:sprintf与snprintf
    转: fscanf()函数详解
    转:fopen()函数
    转:struct sockaddr与struct sockaddr_in ,struct sockaddr_un的区别和联系
    转:BZERO()等的区别
    转:Linux内存管理之mmap详解
  • 原文地址:https://www.cnblogs.com/jonathan236/p/3387593.html
Copyright © 2011-2022 走看看