Dll

/**************************************dll.h****************************************/

#ifndef LIB_H
#define LIB_H
extern "C" void CALLBACK test(HWND hwnd,HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
#endif

/**************************************dll.def****************************************/

LIBRARY Dll
EXPORTS

test @ 4

/**************************************dll.cpp****************************************/

 

 #include "windows.h"
#include "stdio.h"

BOOL APIENTRY DllMain( HANDLE hModule,   
/*
进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识进程自己还有一个HINSTANCE句柄。
所有这些模块句柄都只有在特定的进程内部有效,它们代表了DLL或EXE模块在进程虚拟空间中的起始
地址。在Win32中,HINSTANCE和HMODULE的值是相同的,这两种类型可以替换使用。进程模块句柄几乎
总是等于0x400000,而DLL模块的加载地址的缺省句柄是0x10000000。如果程序同时使用了几个DLL模
块,每一个都会有不同的HINSTANCE值。这是因为在创建DLL文件时指定了不同的基地址,或者是因为
加载程序对DLL代码进行了重定位。
*/
DWORD  ul_reason_for_call,
LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:
  MessageBox(NULL,"DLL 开始加载。。","消息",MB_OK|MB_ICONASTERISK);
  break;
 case DLL_THREAD_ATTACH:
  //MessageBox(NULL,"DLL_THREAD_ATTACH - 2","错误",MB_OK|MB_ICONASTERISK);
  break;
 case DLL_THREAD_DETACH:
  //MessageBox(NULL,"DLL_THREAD_DETACH - 3","错误",MB_OK|MB_ICONASTERISK);
  break;
 case DLL_PROCESS_DETACH:
  //MessageBox(NULL,"DLL 退出","错误",MB_OK|MB_ICONERROR);
  break;
    }
    return TRUE;
}
void CALLBACK test(HWND hwnd,HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
 char sztemp[255];
 GetModuleFileName(hinst,sztemp,sizeof(sztemp));
 MessageBox (NULL,sztemp,"调用程序是:",MB_OK|MB_ICONASTERISK);
 MessageBox (NULL,lpszCmdLine,"传入的参数是:",MB_OK|MB_ICONASTERISK);
 /*
 RUNDLL32.EXE是如何装载DLL并调用其中函数的?

一、操作系统
  Windows 95/98/ME提供rundll.exe和rundll32.exe,前者用来处理16位的DLL,后者用来处理32位的DLL,而NT/2000/XP/2003则只提供rundll32.exe。除此之外,两个程序的行为没什么不同。

二、命令行格式
  RUNDLL32.EXE <DLL名>,<函数名> <可选的参数>
  例如:RUNDLL32.EXE MyDll.DLL,TheFunction Hello World
  则RUNDLL32会装载名为MyDLL.DLL的动态链接库,并调用动态链接库中的函数TheFunction,向它传递参数’Hello World’

三、注意事项
  1、如果没有指名DLL的路径全名,那么RUNDLL32按以下顺序搜索DLL:
    a、RUNDLL32所在的目录
    b、当前目录
    c、系统目录(98通常为WINDOWS安装目录下面的SYSTEM目录、NT和2000通常为WINDOWS安装目录下面的SYSTEM32目录)
    d、如果是NT和2000系统,搜索16位系统目录,即WINDOWS安装目录下面的SYSTEM目录
    e、WINDOWS安装目录
    f、PATH环境变量中指明的搜索路径
  2、建议使用DLL的全路径名,但推荐用短文件名,因为RUNDLL32无法识别路径全名中包含的空格。
  3、DLL文件名中不能包含空格、逗号和引号。
  4、DLL名和函数名之间必须有一个逗号(,),且逗号前后不能有空格。

四、RUNDLL32如何工作
  RUNDLL32按以下步骤工作:
  1、分析命令行
  2、用LoadLibrary()这个API来装载DLL
  3、用GetProcAddress()这个API来找到函数入口点
  4、调用函数,把<可选参数>做为命令行传递给函数
  5. 函数返回后,用FreeLibrary()来卸掉DLL
  6、结束RUNDLL32程序的运行

五、如何编写DLL中的函数
  DLL中的函数应该这样写(不考虑16位DLL):

  C语言: void CALLBACK TheFunction(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
  PASCAL:procedure TheFunction(AWnd, AInst: THandle; ACmdLine: PChar; ACmdShow: Integer); stdcall;

  请注意:函数的调用约定必须是stdcall,否则RUNDLL32可能会出错。

六、示例

  RUNDLL32.EXE MyDll.DLL,TheFunction Hello World
  则TheFunction收到的参数如下:
   AWnd:    父窗口句柄
   AInst:   MyDLL.DLL的句柄 
   ACmdLine:字符串(以零结尾)’Hello World’
   ACmdShow:如何显示窗口

七、UNICODE系统
  从NT开始的WINDOWS都是基于UNICODE的,因为,在这样的环境下,RUNDLL32首先尝试在函数名后面加个W,如果没找到这个函数,就尝试在函数名后面加A,如果还没有找到,再用提供的函数名。如果添加W字符后找到函数,则lpszCmdLine传递的是宽字符串。

  */
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值