关于我想要编写dll文件这件事

Ustinain 28 1 1

0x1前言

首先我们要用C、C++编写dll,肯定是需要一个合适的编写软件,什么!?你不知道什么是dll,那你这有必要去看看我得上一篇《初识Windows APi》了虽然篇幅不长,但是可以让你对dll有个大致得印象,由于本人用的CLion 2019的版本的,至于为什么不用VS,因为里面配置过于繁琐,很不友好,CLion安装包以及破解 群文件都有,可以去下载直接使用。话不多说,进入今天的正题:


利用C、C++简单的编写一个DLL文件

::: tip 开发环境:CLion 2019.3.3 编译器:WinGW64 ::: 打开CLion 新建一个 C Library项目DLL image library.c默认代码 image 按下Ctrl+F9编译,右侧生成libDLL.dll文件 image

调用dll

新建一个项目 untitled1 ,在untitled1下创建一个lib目录,存放刚刚生成的dll文件, image 配置CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
#项目名
project(untitled1 )

set(CMAKE_C_STANDARD 99)

#新增:指项目根目录下的lib目录
link_directories(lib)

add_executable(untitled1 main.c )

#新增:目标链接的dll文件
target_link_libraries(untitled1 libDLL.dll)

配置main.c:

#include <stdio.h>
void hello();
int main() {
    printf("下面是一个dll的调用");
    hello();
    getchar();
    return 0;
}

配置Configurations: 将lib目录的绝对路径填入(如用群里的中文插件可能导致这里显示异常) image 然后编译运行结果如下: image 到这里只是用实操演示一下dll的由来,只能对编写dll有一个认识,当然无法准确的理解,那么请继续往下看


详解

这里介绍一下dll动态链接库的核心入口函数 DLLMain() 跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain。 以"DllMain"为关键字,来看看MSDN帮助文档怎么介绍这个函数的。

The DllMain function is an optional method of entry into a dynamic-link library (DLL) 。 (简要翻译:对于一个Dll模块,DllMain函数是可选的。)这句话很重要,很多初学者可能都认为一个动态链接库肯定要有DllMain函数。其实不然,像很多仅仅包含资源信息的DLL是没有DllMain函数的。

#include <windows.h>
_Bool WINAPI DllMain(HINSTANCE hinstDLL,  // handle to DLL module       
                    DWORD fdwReason,     // reason for calling function 
                    LPVOID lpReserved )  // reserved                    
{                                                                       
    // Perform actions based on the reason for calling.                 
    switch( fdwReason)                                                  
    {                                                                   
    case DLL_PROCESS_ATTACH:                                            
    // Initialize once for each new process.                            
    // Return FALSE to fail DLL load.                                   
        break;                                                          

    case DLL_THREAD_ATTACH:                                             
    // Do thread-specific initialization.                               
        break;                                                          

    case DLL_THREAD_DETACH:                                             
    // Do thread-specific cleanup.                                      
        break;                                                          

    case DLL_PROCESS_DETACH:                                            
    // Perform any necessary cleanup.                                   
        break;                                                          
}                                                                       
    return TRUE;  // Successful DLL_PROCESS_ATTACH.                     
}                                                                       

因为返回类型是布尔类型,所以最后要return true hinstDLL参数:DLL模块的句柄。该值是DLL的基地址;

fdwReason [in]参数:指明了DLL被调用的原因,可以有以下4个取值: ::: tip

1. DLL_PROCESS_ATTACH: 当DLL被进程 <第一次>调用时,导致DllMain函数被调用, 同时ul_reason_for_call的值为DLL_PROCESS_ATTACH, 如果同一个进程后来再次调用此DLL时,操作系统只会增加DLL的使用次数, 不会再用DLL_PROCESS_ATTACH调用DLL的DllMain函数。

2.DLL_PROCESS_DETACH: 当DLL被从进程的地址空间解除映射时,系统调用了它的DllMain,传递的ul_reason_for_call值是DLL_PROCESS_DETACH。 ★如果进程的终结是因为调用了TerminateProcess,系统就不会用DLL_PROCESS_DETACH来调用DLL的DllMain函数。这就意味着DLL在进程结束前没有机会执行任何清理工作。

3.DLL_THREAD_ATTACH: 当进程创建一线程时,系统查看当前映射到进程地址空间中的所有DLL文件映像,并用值DLL_THREAD_ATTACH调用DLL的DllMain函数。 新创建的线程负责执行这次的DLL的DllMain函数, 只有当所有的DLL都处理完这一通知后,系统才允许线程开始执行它的线程函数。

4.DLL_THREAD_DETACH: 如果线程调用了ExitThread来结束线程(线程函数返回时,系统也会自动调用ExitThread),系统查看当前映射到进程空间中的所有DLL文件映像,并用DLL_THREAD_DETACH来调用DllMain函数,通知所有的DLL去执行线程级的清理工作。 ::: ::: warning ★如果线程的结束是因为系统中的一个线程调用了TerminateThread,系统就不会用值DLL_THREAD_DETACH来调用所有DLL的DllMain函数。 ::: lpReserved参数:系统保留,不让我们利用,目前没什么意义。 不过关于lPReserved参数,看到一位网友是这样说的:

“lpvReserved:为零表示隐式载入,不为零表示显示载入 不是没有什么意义”,我还没有深究,暂做参考

预览图
收藏
评论区
守株待兔
最新文章
dll导出函数 2021-04-14 22:42
初识Windows API 2021-04-01 21:13
C语言_练习题(一) 2021-03-17 21:38
C语言_练习题(一) 2021-03-17 21:38
C语言_二进制文件 2021-03-15 21:36

导读