`
conkeyn
  • 浏览: 1529706 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

DllMain函数

阅读更多

Windows在加载DLL的时候,需要一个入口函数,就如同控制台或DOS程序需要main函数、WIN32程序需要WinMain函数一样。在前面的 例子中,DLL并没有提供DllMain函数,应用工程也能成功引用DLL,这是因为Windows在找不到DllMain的时候,系统会从其它运行库中 引入一个不做任何操作的缺省DllMain函数版本,并不意味着DLL可以放弃DllMain函数。

  根据编写规范,Windows必须查找并执行DLL里的DllMain函数作为加载DLL的依据,它使得DLL得以保留在内存里。这个函数并不属于导出函数,而是DLL的内部函数。这意味着不能直接在应用工程中引用DllMain函数,DllMain是自动被调用的。

  我们来看一个DllMain函数的例子(单击此处下载本工程附件 )。

BOOL APIENTRY DllMain( HANDLE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved

)

{

switch (ul_reason_for_call)

{

case DLL_PROCESS_ATTACH:

printf("\nprocess attach of dll");

break;

case DLL_THREAD_ATTACH:

printf("\nthread attach of dll");

break;

case DLL_THREAD_DETACH:

printf("\nthread detach of dll");

break;

case DLL_PROCESS_DETACH:

printf("\nprocess detach of dll");

break;

}

return TRUE;

}


   DllMain函数在DLL被加载和卸载时被调用,在单个线程启动和终止时,DLLMain函数也被调用,ul_reason_for_call指明了 被调用的原因。原因共有4种,即PROCESS_ATTACH、PROCESS_DETACH、THREAD_ATTACH和 THREAD_DETACH,以switch语句列出。
来仔细解读一下DllMain的函数头BOOL APIENTRY DllMain( HANDLE hModule, WORD ul_reason_for_call, LPVOID lpReserved )。

  APIENTRY被定义为__stdcall,它意味着这个函数以标准Pascal的方式进行调用,也就是WINAPI方式;

   进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识,只有在特定的进程内部有效,句柄代表了DLL模块在进程虚拟空间中的起始地 址。在Win32中,HINSTANCE和HMODULE的值是相同的,这两种类型可以替换使用,这就是函数参数hModule的来历。

  执行下列代码:

hDll = LoadLibrary("..\\Debug\\dllTest.dll");

if (hDll != NULL)

{

addFun = (lpAddFun)GetProcAddress(hDll, MAKEINTRESOURCE(1));

//MAKEINTRESOURCE直接使用导出文件中的序号

if (addFun != NULL)

{

int result = addFun(2, 3);

printf("\ncall add in dll:%d", result);

}

FreeLibrary(hDll);

}



  我们看到输出顺序为:

  process attach of dll

  call add in dll:5

  process detach of dll

  这一输出顺序验证了DllMain被调用的时机。

   代码中的GetProcAddress ( hDll, MAKEINTRESOURCE ( 1 ) )值得留意,它直接通过.def文件中为add函数指定的顺序号访问add函数,具体体现在MAKEINTRESOURCE ( 1 ),MAKEINTRESOURCE是一个通过序号获取函数名的宏,定义为(节选自winuser.h):

#define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i)))

#define MAKEINTRESOURCEW(i) (LPWSTR)((DWORD)((WORD)(i)))

#ifdef UNICODE

#define MAKEINTRESOURCE MAKEINTRESOURCEW

#else

#define MAKEINTRESOURCE MAKEINTRESOURCEA

分享到:
评论

相关推荐

    让易语言的DLL不依赖任何插件都能拥有完整的入口函数(DllMain)

    首先,我们来理解DllMain函数。DllMain是DLL的核心入口点,当DLL被加载到进程地址空间或卸载时,操作系统会调用这个函数。这个函数的主要任务包括初始化和清理工作,如分配内存、设置全局变量、注册COM组件等。根据...

    DLL的进入点函数DllMain

    "DLL的进入点函数DllMain" DLL 的进入点函数 DllMain 是一个非常重要的概念,在Dynamic Link Library(动态链接库)中扮演着核心角色。DllMain 函数是 DLL 的入口点,系统在不同的情况下会调用它,并传递不同的参数...

    易语言让EXE程序也能拥有DllMain通知源码

    在Windows系统中,DLL(动态链接库)是共享代码和资源的重要方式,其中的DllMain函数是DLL的入口点,用于处理进程和线程的初始化与清理工作。通常,只有DLL才能拥有DllMain函数,但通过特定的技术手段,EXE程序也...

    VS2010中使用C++创建和使用DL.docx

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

    DllMain和多线程死锁[归类].pdf

    在装载 DLL 时,某个 DLL 的 DllMain 启动了一个线程,然后立即调用一个应答事件对象的 WaitForSingleObject 函数,以确认在继续进行其余的 DllMain 处理之前,新产生的线程能够正确地执行一些操作。如果不遵守 ...

    DLL创建与函数调用规则

    对于Extension DLL,由于没有从CWinApp派生的对象,需要自行编写DLLMain函数并调用`AfxInitExtensionModule`初始化模块,同时需要处理CRuntimeClass对象和资源的初始化。 DLLMain函数是每个DLL的入口点,负责初始化...

    DLL编程代码

    在DLL编程中,"dllTest4_DLLMain函数"是一个关键的元素。DLLMain函数是每个DLL的入口点,类似于应用程序的WinMain或main函数。当DLL被加载到进程空间时,DLLMain函数会被自动调用。这个函数通常用于初始化和清理资源...

    MFC扩展DLL

    MFC扩展DLL与MFC常规DLL之间的主要区别在于它们如何处理CWinApp对象和DllMain函数。在MFC常规DLL中,CWinApp对象是由MFC向导自动添加的,而MFC扩展DLL则没有这个对象,但包含了DllMain函数。开发人员需要在MFC扩展...

    VC++动态链接库(DLL)编程深入浅出,DLL编写教程 两篇

    最简单的dll并不比c的helloworld难,只要一个DllMain函数即可,包含objbase.h头文件(支持COM技术的一个头文件)。若你觉得这个头文件名字难记,那么用windows.H也可以。源代码如下:dll_nolib.cpp #include #...

    关于dll加载后调用函数的问题.md

    首先,我们在写DLL的时候,需要在DLL函数里面加上DllMain函数,可以在这里面写上你自己的函数,windows在用LoadLibrary加载DLL后调用会DllMain函数,而你把自己的函数已经先写在在DllMain里面了,那么你的函数也自然就执行...

    uafxcwd.lib LIBCMTD.lib 弱外部链接

    CRT 库对 new、delete 和 DllMain 函数使用弱外部链接。MFC 库也包含 new、delete 和 DllMain 函数。这些函数要求先链接 MFC 库,然后再链接 CRT 库。 当 C 运行时 (CRT) 库和 Microsoft 基础类 (MFC) 库的链接顺序...

    操作系统原理实验七.doc

    2. 入口函数DllMain:每个DLL都有一个DllMain函数,它是DLL的初始化点,根据ul_reason_for_call参数执行相应操作。 3. 导入/导出函数:使用_declspec(dllexport)导出DLL中的函数,_declspec(dllimport)导入DLL函数。...

    Detours API HOOK快速入门

    3. **DllMain函数**:在你的DLL的DllMain函数中,根据`DLL_PROCESS_ATTACH`事件来安装Hook。在Hook安装过程中,通常会使用Detours提供的API,如`DetourAttach()`,来指定要Hook的函数地址。 4. **钩子函数**:创建...

    DLL编程深入浅出带源码

    4.4 DllMain函数 4.5 __stdcall约定 4.6 DLL导出变量 4.7 DLL导出类 5. MFC规则DLL 5.1 概述 5.2 MFC规则DLL的创建 5.3 一个简单的MFC规则DLL 5.4 MFC规则DLL的调用 5.5 共享MFC DLL的规则DLL的模块切换 6.1 MFC扩展...

    【易语言插件】静态库调试支持插件.zip

    众所周知,易语言需要静态编译才能调用静态库,导致我们在调试运行非常不方便。...报的警告LNK4001是因为没有定义DllMain函数,它会使用默认的DllMain函数的警告,属于正常,无需理会。 插件是开源的。

    编写C语言DLL,及C调用DLL.docx

    在这个例子中,我们在dllmain.cpp文件中编写了HelloWorld函数和DllMain函数。HelloWorld函数是一个简单的函数,用于弹出一个消息框,显示“Hello World from DLL!”的信息。DllMain函数是DLL的入口点,用于初始化...

    易语言-让易语言的DLL不依赖任何插件都能拥有完整的入口函数(DllMain)

    2. **定义DllMain函数**:在易语言中,我们需要声明和实现DllMain函数。DllMain函数的原型如下: ```易语言 .入口点 DllMain .参数 hinstDLL, DLL惯性 .参数 fdwReason, 原因 .参数 lpvReserved, 预留 .返回值...

    ObjectARX及MFC开发常见的问题及解决方法总结.doc

    解决方案是删除自定义的DllMain函数,或者在DllMain文件中添加特定代码以确保执行自定义的DllMain函数。 5. **创建ObjectARX工程的注意事项**:在创建ObjectARX程序时,需要选择"MFC AppWizard(DLL)",然后选择MFC ...

    驱动模拟键鼠源代码,支持64位WIN7含代码

    驱动模拟键鼠源代码,支持64位WIN7,64位WIN7要在禁止驱动签名强制下运行 myASSoft.rar中的代码为驱动。...请参看里面的DllMain函数 kmclass64.sys和kmclass.sys为编译好的驱动。使用时请改名为kmclass.sys。

    pe2-DLL.rar_This Is It

    4. DllMain函数:DLL的入口点通常是DllMain函数,它会在DLL加载和卸载时被调用。DllMain允许DLL执行初始化和清理任务。 5. 导入地址表(IAT)处理:DLL中的函数通过导入地址表供其他模块调用。加载时,系统会解析...

Global site tag (gtag.js) - Google Analytics