利用vs2010制作C语言 dll文件,并在其它程序中调用该dll文件

一、为什么需要dll

代码复用是提高软件开发 效率的重要途径。一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用。比较常见的例子是各种应用程序框架, 如ATL、MFC等,它们都以源代码的形式发布。由于这种复用是“源码级别”的,源代码完全暴露给了程序员,因而称之为“白盒复用”。“白盒复用”的缺点 比较多,总结起来有4点。

  1. 暴露了源代码;
  2. 容易与程序员的“普通”代码发生命名冲突;
  3. 多份拷贝,造成存储浪费;
  4. 更新功能模块比较困难。

实际上,以上4点概括起来就是“暴露的源代码”造成“代码严重耦合”。为了弥补这些不足,就提出了“二进制级别”的代码复用。使用二进制级别的代码复用一定程度上隐藏了源代码,对于缓解代码耦合现象起到了一定的作用。这样的复用被称为“黑盒复用”。

在Windows操作系 统中有两种可执行文件,其后缀名分别为.exe和.dll。它们的区别在于,.exe文件可被独立的装载于内存中运行;.dll文件却不能,它只能被其它 进程调用。然而无论什么格式,它们都是二进制文件。上面说到的“二进制级别”的代码复用,可以使用.dll来实现。

与白盒复用相 比,.dll很大程度上弥补了上述4大缺陷。.dll是二进制文件,因此隐藏了源代码;如果采用“显式调用”(后边将会提到),一般不会发生命名冲突;由 于.dll是动态链接到应用程序中去的,它并不会在链接生成程序时被原原本本拷贝进去;.dll文件相对独立的存在,因此更新功能模块是可行的。

说明:实现“黑盒复用”的途径不只dll一种,静态链接库甚至更高级的COM组件都是。本文只对dll进行讨论。

二、C语言制作dll文件

1. 启动vs2010, 

2.创建dll工程

  a. 文件 -> 新建 ->  项目 -> win32控制台应用程序 —> 

  b. 输入工程名称, 比如 dll, 点击确定

  c. 点击下一步, 在“应用程序设置界面” 勾选 dll 和空项目, 点击完成按钮

  d. 视图 -> 解决方案资源管理器 ->右键点击头文件, 添加->新建项,这里用dll.h,

  e. 右键点击"源文件",添加->新建项,这里我们添加dll.c,到此dll工程搭建完毕. 

3. dll.h

#ifndef AXLPLUGIN_H  
#define AXLPLUGIN_H  
/**/  
#ifdef _WINDOWS  
#define DLL_DECLARE __declspec(dllexport)  
#else  
#define DLL_DECLARE  
#endif  
DLL_DECLARE int Min(int a, int b);  
/* 把所有的函数声明都列在这里 */  
#endif  

4. dll.c

#include "dll.h"  
#include <stdio.h>  
/*根据需要添加相应的头文件*/  
DLL_DECLARE int Min(int a, int b)  
{  
    if (a >= b)   
        return b;  
    else   
        return a;  
}  
/* 把所有声明的函数都在这里实现*/  

5. 生成dll lib 文件

点击build -> build dll

这样,dll 和 lib 文件就生成了。

5. dll文件的使用

试验证明dll.dll文件要和dll.lib以及dll.h文件一起使用  

三 ,在程序中加载dll

  1. 新建一个测试用的"Win32应用程序"  
  2. 操作:

    a.文件->新建->项目->Win32控制台应用程序.

    b.输入工程名称,这里我们用test_dll,点击确定按钮.  

       c.点击下一步,在"应用程序设置界面设置"控制台应用程序"和"空项目",点击完成按钮.  

       d.将工程dll目录里的dll.h/dll.dll/dll.lib拷贝到工程test_dll目录里。  

       e.视图->解决方案资源管理器,右键点击"头文件",添加->新建项,这里咱们用dll.h  

         右键点击"源文件",添加->新建项,这里我们添加test_dll.c,右键点击“资源文件”,  

         添加->"现有项",选择dll.lib,到此test_dll工程搭建完毕.   

  3.  编辑test_dll.c文件,内容如下 

#include "dll.h"  
#include <stdio.h>  
int main()  
{  
    printf("Min(2, 4) = %d
", Min(2, 4));  
    printf("Min(5, 2) = %d
", Min(5, 2));  
    return 0;  
}  

四,dll和test_dll工程的目录结构  

../test_dll/  
│  test_dll.sdf  
│  test_dll.sln  
│  test_dll_dir.txt  
├─Debug  
│      test_dll.exe  
│      test_dll.ilk  
│      test_dll.pdb        
├─ipch  
│  └─test_dll-eb5063a1  
│          test_dll-c06c53e7.ipch           
└─test_dll  
    │  dll.dll  
    │  dll.h  
    │  dll.lib  
    │  test_dll.c  
    │  test_dll.vcxproj  
    │  test_dll.vcxproj.filters  
    │  test_dll.vcxproj.user   
    └─Debug  
            cl.command.1.tlog  
            CL.read.1.tlog  
            CL.write.1.tlog  
            link-cvtres.read.1.tlog  
            link-cvtres.write.1.tlog  
            link.3004-cvtres.read.1.tlog  
            link.3004-cvtres.write.1.tlog  
            link.3004.read.1.tlog  
            link.3004.write.1.tlog  
            link.command.1.tlog  
            link.read.1.tlog  
            link.write.1.tlog  
            mt.command.1.tlog  
            mt.read.1.tlog  
            mt.write.1.tlog  
            rc.command.1.tlog  
            rc.read.1.tlog  
            rc.write.1.tlog  
            test_dll.Build.CppClean.log  
            test_dll.exe.embed.manifest  
            test_dll.exe.embed.manifest.res  
            test_dll.exe.intermediate.manifest  
            test_dll.lastbuildstate  
            test_dll.log  
            test_dll.obj  
            test_dll_manifest.rc  
            vc100.idb  
            vc100.pdb
原文地址:https://www.cnblogs.com/wangjz/p/4808803.html