c++生成dll文件入门

安装visual studio community 2019,勾选c++桌面开发。参考文章:https://www.cnblogs.com/xmr183729/p/13307265.html;截取前半部分进行操作,用于了解dll的编写(notepad++中编写code)、编译、生成、调用、执行。
dll文件:.cpp → cl 命令 → .obj → Link命令 → .dll
调用dll文件:.cpp → cl命令 → .obj 和.exe

  • 1、将cl.exe所在目录追加到PATH环境变量中
  • 2、配置cl.exe依赖的环境变量(使用msvc的cl工具编译程序,以及 “fatal error C1034: iostream: 不包括路径集”等问题解决):https://blog.csdn.net/weixin_41115751/article/details/89817123
  • 3、cl /c /EHsc dll_nolib.cpp,生成dll_nolib.obj文件
D:\Cpath\studyDir\dllWorld>cl /c /Ehsc dll_nolib.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。

cl: 命令行 warning D9002 :忽略未知选项“/Ehsc”
dll_nolib.cpp
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\ostream(746): warning C4530: 使用了 C++ 异常处理程序,但未启用展开语义。请指定 /EHsc
dll_nolib.cpp(12): note: 查看对正在编译的函数 模板 实例化“std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char *)”的引用
  • 4、Link /dll dll_nolib.obj,生成dll_nolib.dll文件
D:\Cpath\studyDir\dllWorld>Link /dll dll_nolib.obj
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.
  • 5、Cl /EHsc dll_nolib_client.cpp,生成dll_nolib_client.exe文件
D:\Cpath\studyDir\dllWorld>Cl /EHsc dll_nolib_client.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。

dll_nolib_client.cpp
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:dll_nolib_client.exe
dll_nolib_client.obj
  • 6、命令行中执行dll_nolib_client.exe,能看到dll已经被客户端加载过。但是这样仅仅能够将dll加载到内存,不能找到dll中的函数
D:\Cpath\studyDir\dllWorld>dll_nolib_client.exe
Dll被加载到进程中
dll loaded!
dll从进程中卸载

3-6的code

// 文件dll_nolib.cpp
#include <objbase.h>
#include <iostream>
using namespace std;

BOOL APIENTRY DllMain( HANDLE hModule, DWORD dwReason, void* lpReserved)
{
    HANDLE g_hModule;
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
        cout << "Dll被加载到进程中" << endl;
        g_hModule = (HINSTANCE)hModule;
        break;
    case DLL_THREAD_ATTACH:
        cout << "Dll被加载到线程中" << endl;
        g_hModule = (HINSTANCE)hModule;
        break;
    case DLL_THREAD_DETACH:
        cout << "dll从线程中卸载" << endl;
        g_hModule = (HINSTANCE)hModule;
        break;
    case DLL_PROCESS_DETACH:
        cout << "dll从进程中卸载" << endl;
        g_hModule = (HINSTANCE)hModule;
        break;
    }
    return TRUE;
}
// 文件dll_nolib_client.cpp
#include <windows.h>
#include <iostream>
using namespace std;

int main(void){
    //加载我们的dll
    HINSTANCE hinst = ::LoadLibrary("dll_nolib.dll");
    if (NULL != hinst){
        cout << "dll loaded!" << endl;
    }
    return 0;
}
  • 7、dumpbin -exports dll_nolib.dll,查看dll中的函数
D:\Cpath\studyDir\dllWorld>dumpbin -exports dll_nolib.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file dll_nolib.dll

File Type: DLL

  Summary

        3000 .data
        3000 .pdata
       11000 .rdata
        1000 .reloc
       22000 .text
        1000 _RDATA

  • 8、添加def定义文件来输出函数
D:\Cpath\studyDir\dllWorld>cl /c /EHsc dll_def.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。

dll_def.cpp
D:\Cpath\studyDir\dllWorld>Link /dll dll_def.obj /def:dll_def.def
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.

dll_def.def(6) : warning LNK4017: DESCRIPTION 语句不支持目标平台;已忽略
  正在创建库 dll_def.lib 和对象 dll_def.exp
  D:\Cpath\studyDir\dllWorld>dumpbin -exports dll_def.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file dll_def.dll

File Type: DLL

  Section contains the following exports for dll_def.dll

    00000000 characteristics
    FFFFFFFF time date stamp
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001110 FuncInDll

  Summary

        3000 .data
        3000 .pdata
       12000 .rdata
        1000 .reloc
       22000 .text
        1000 _RDATA
D:\Cpath\studyDir\dllWorld>cl /EHsc dll_def_client.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。

dll_def_client.cpp
dll_def_client.cpp(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:dll_def_client.exe
dll_def_client.obj

8的code

// dll_def.cpp
#include <objbase.h>
#include <iostream>
using namespace std;

void FuncInDll(void){
    cout<<"FuncInDll is called!"<<endl;
}

BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved){
    HANDLE g_hModule;
    switch(dwReason){
        case DLL_PROCESS_ATTACH:
            cout<<"dllMain方法:加载到进程中!"<<endl;
            g_hModule = (HINSTANCE)hModule;
            break;
        case DLL_PROCESS_DETACH:
            g_hModule=NULL;
            break;
    }
    return TRUE;
}
// dll_def.def
;
; dll_def module-definition file
;

LIBRARY         dll_def.dll
DESCRIPTION     '(c)2021 qiaosong'
EXPORTS
                FuncInDll @1 PRIVATE
//dll_def_client.cpp
#include <windows.h>
#include <iostream>
using namespace std;

int main(void){
    //定义一个函数指针
    typedef void (* DLLWITHLIB )(void); 
    //定义一个函数指针变量
    DLLWITHLIB pfFuncInDll = NULL; 
    //加载我们的dll
    HINSTANCE hinst=::LoadLibrary("dll_def.dll"); 
    if (NULL != hinst){
       cout<<"dll loaded!"<<endl;
    }
    //找到dll的FuncInDll函数
    pfFuncInDll = (DLLWITHLIB)GetProcAddress(hinst, "FuncInDll"); 
    //调用dll里的函数
    if (NULL != pfFuncInDll)
    {
       (*pfFuncInDll)();  
    }
    return 0;
}
  • 9、_declspec(dllexport)导出函数
D:\Cpath\studyDir\dllWorld\V3>cl /c /EHsc dll_declsec.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。

dll_declsec.cpp
D:\Cpath\studyDir\dllWorld\V3>Link /dll dll_declsec.obj
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.

  正在创建库 dll_declsec.lib 和对象 dll_declsec.exp
D:\Cpath\studyDir\dllWorld\V3>Link /dll dll_declsec.obj
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.

  正在创建库 dll_declsec.lib 和对象 dll_declsec.exp

D:\Cpath\studyDir\dllWorld\V3>dir
 驱动器 D 中的卷是 工作
 卷的序列号是 C14D-581B

 D:\Cpath\studyDir\dllWorld\V3 的目录

2021/07/21  22:17    <DIR>          .
2021/07/21  22:17    <DIR>          ..
2021/07/21  22:15               483 dll_declsec.cpp
2021/07/21  22:17           227,840 dll_declsec.dll
2021/07/21  22:17               710 dll_declsec.exp
2021/07/21  22:17             1,794 dll_declsec.lib
2021/07/21  22:15           178,117 dll_declsec.obj
2021/07/21  22:06               598 dll_declsec_client.cpp
               6 个文件        409,542 字节
               2 个目录 102,568,783,872 可用字节

D:\Cpath\studyDir\dllWorld\V3>dumpbin -exports dll_declsec.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file dll_declsec.dll

File Type: DLL

  Section contains the following exports for dll_declsec.dll

    00000000 characteristics
    FFFFFFFF time date stamp
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001110 ?FuncInDll@@YAXXZ

  Summary

        3000 .data
        3000 .pdata
       12000 .rdata
        1000 .reloc
       22000 .text
        1000 _RDATA
D:\Cpath\studyDir\dllWorld\V3>cl /EHsc dll_declsec_client_LoadErrorFunc.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。

dll_declsec_client_LoadErrorFunc.cpp
dll_declsec_client_LoadErrorFunc.cpp(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:dll_declsec_client_LoadErrorFunc.exe
dll_declsec_client_LoadErrorFunc.obj

D:\Cpath\studyDir\dllWorld\V3>cl /EHsc dll_declsec_client_LoadRightFunc.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。

dll_declsec_client_LoadRightFunc.cpp
dll_declsec_client_LoadRightFunc.cpp(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:dll_declsec_client_LoadRightFunc.exe
dll_declsec_client_LoadRightFunc.obj
D:\Cpath\studyDir\dllWorld\V3>dll_declsec_client_LoadRightFunc.exe
dllMain func锛歭oaded in memory!
dll loaded!
FuncInDll is called!

D:\Cpath\studyDir\dllWorld\V3>dll_declsec_client_LoadErrorFunc.exe
::LoadLibrary("dll_declsec.dll")====> return null
not found FuncInDll function

9的code

//dll_declsec.cpp
#include <objbase.h>
#include <iostream>
using namespace std;

extern "C" __declspec(dllexport) void FuncInDll(void){
    cout<<"FuncInDll is called!"<<endl;
}

BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved){
    HANDLE g_hModule;
    switch(dwReason){
        case DLL_PROCESS_ATTACH:
            cout<<"dllMain func:loaded in memory!"<<endl;
            g_hModule = (HINSTANCE)hModule;
            break;
        case DLL_PROCESS_DETACH:
            g_hModule=NULL;
            break;
    }
    return TRUE;
}
//dll_declsec_client_LoadErrorFunc.cpp
#include <windows.h>
#include <iostream>
using namespace std;

int main(void){
    //定义一个函数指针
    typedef void (* DLLWITHLIB )(void); 
    //定义一个函数指针变量
    DLLWITHLIB pfFuncInDll = NULL; 
    //加载我们的dll
    HINSTANCE hinst=::LoadLibrary("dll_declsec2.dll"); 
    if (NULL != hinst){
       cout<<"dll loaded!"<<endl;
    }else{
        cout<<"::LoadLibrary(\"dll_declsec.dll\")====> return null"<<endl;
    }
    //找到dll的FuncInDll函数
    pfFuncInDll = (DLLWITHLIB)GetProcAddress(hinst, "FuncInDll"); 
    //调用dll里的函数
    if (NULL != pfFuncInDll)
    {
       (*pfFuncInDll)();  
    }else{
        cout<<"not found FuncInDll function"<<endl;
    }
    return 0;
}
//dll_declsec_client_LoadRightFunc.cpp
#include <windows.h>
#include <iostream>
using namespace std;

int main(void){
    //定义一个函数指针
    typedef void (* DLLWITHLIB )(void); 
    //定义一个函数指针变量
    DLLWITHLIB pfFuncInDll = NULL; 
    //加载我们的dll
    HINSTANCE hinst=::LoadLibrary("dll_declsec.dll"); 
    if (NULL != hinst){
       cout<<"dll loaded!"<<endl;
    }else{
        cout<<"::LoadLibrary(\"dll_declsec.dll\")====> return null"<<endl;
    }
    //找到dll的FuncInDll函数
    pfFuncInDll = (DLLWITHLIB)GetProcAddress(hinst, "FuncInDll"); 
    //调用dll里的函数
    if (NULL != pfFuncInDll)
    {
       (*pfFuncInDll)();  
    }else{
        cout<<"not found FuncInDll function"<<endl;
    }
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容