本文将创建一个简单的动态链接库,并编写一个应用台控制程序使用该动态链接库,并提出了与实现相关的几个问题,供初学者交流。

本文包含以下内容:

创建动态链接库项目

向动态链接库添加类

创建引用动态链接库的应用程序

在控制台应用程序中使用类库的功能

更丰富的simpledll类和相关问题

参考资料

创建动态链接库项目:

1、打开Microsoft Visual Studio 2010,选择File->New->Project。

2、在New Project中选择Installed Templates->Visual C++->Win32。

3、选择Win32 Console Application,设置名称:simpledll,设置解决方案名:zdddll。

4、单击OK,在出现的Win32 Application Wizard的Overview对话框中点击Next。

5、在Application Settings中,选择Application type下的DLL。

6、勾选Additional options下的Empty project。

7、单击Finish创建项目。

向动态链接库添加类:

1、添加新类头文件。右键单击simpledll项目,Add->New Item,选择Header File(.h),设置名称为simpledll,单击Add。

2、添加新类源文件。右键单击simpledll项目,Add->New Item,选择C++ File(.cpp),设置名称为simpledll,单击Add。

3、为新类添加内容。内容如下:

头文件simpledll.h:

  1. //------------------ simpledll.h ----------------
  2. #pragma once;
  3. //该宏完成在dll项目内部使用__declspec(dllexport)导出
  4. //在dll项目外部使用时,用__declspec(dllimport)导入
  5. //宏DLL_IMPLEMENT在simpledll.cpp中定义
  6. #ifdef DLL_IMPLEMENT
  7. #define DLL_API __declspec(dllexport)
  8. #else
  9. #define DLL_API __declspec(dllimport)
  10. #endif
  11. namespace zdd
  12. {
  13. //导出类
  14. class DLL_API SimpleDll
  15. {
  16. public:
  17. SimpleDll();
  18. ~SimpleDll();
  19. int add(int x, int y); //简单方法
  20. };
  21. }

源文件simpledll.cpp:

  1. //------------------ simpledll.cpp ----------------
  2. //注意此处的宏定义需要写在#include "simpledll.h"之前
  3. //以完成在dll项目内部使用__declspec(dllexport)导出
  4. //在dll项目外部使用时,用__declspec(dllimport)导入
  5. #define DLL_IMPLEMENT
  6. #include "simpledll.h"
  7. namespace zdd
  8. {
  9. SimpleDll::SimpleDll()
  10. {
  11. }
  12. SimpleDll::~SimpleDll()
  13. {
  14. }
  15. int SimpleDll::add(int x, int y)
  16. {
  17. return x+y;
  18. }
  19. }

4、完成后点击Build->Build Solution,生成解决方案。可在~zdddll\Debug下查看生成的simpledll.lib和simpledll.dll.文件。

创建引用动态链接库的应用程序:

1、选择File->New->Project。

2、在New Project中选择Installed Templates->Visual C++->Win32。

3、选择Win32 Console Application,设置名称:usesimpledll。选择Add to solution。

4、单击OK,在出现的Win32 Application Wizard的Overview对话框中点击Next。

5、在Application Settings中,选择Application type下的Console application。

6、取消Additional options下的Precompiled header,勾选Empty project。

7、单击Finish创建项目。

在控制台应用程序中使用类库的功能:

1、为控制台应用程序添加main.cpp。右键单击usesimpledll项目,Add->New Item,选择C++ File(.cpp),设置名称为main,单击Add。

2、为main.cpp添加内容。如下所示:

  1. //------------------ main.cpp -------------------
  2. #include "simpledll.h"
  3. using namespace zdd;
  4. #include <iostream>
  5. using namespace std;
  6. int main(char argc, char**argv)
  7. {
  8. //
  9. cout << "----------------------" <<endl;
  10. SimpleDll sd;
  11. cout << "sd.add: 3+5=" << sd.add(3, 5)<<endl;
  12. cout << "sd.getConst(): "<<sd.getConst()<<endl;
  13. SimpleDll *psd = new SimpleDll;
  14. cout << "psd->add: 5+5=" << psd->add(5, 5)<<endl;
  15. cout << "psd->getConst(): "<<endl;
  16. cout << "----------------------" <<endl;
  17. cout << "please press Enter exit."<<endl;
  18. getchar();
  19. return 0;
  20. }

3、引用simpledll项目。右键单击usesimpledll项目,选择Properties->Common Properties->Framework and References。点击Add New Reference,选择simpledll项目,单击OK。

4、设置头文件路径。选择Properties->Configuration Properties->VC++ Directories。在Include Directories项添加$(SolutionDir)\simpledll\,选择应用,确定。

5、设置usesimpledll项目为活动项目。右键单击usesimpledll项目,选择Set up StartUp Project。

6、生成解决方案。Debug运行结果如下:

  1. 3+5=8
  2. 5+5=10

更丰富的simpledll类和相关问题:

simpledll.h文件:

  1. //------------------ simpledll.h ----------------
  2. #pragma once;
  3. //该宏完成在dll项目内部使用__declspec(dllexport)导出
  4. //在dll项目外部使用时,用__declspec(dllimport)导入
  5. //宏DLL_IMPLEMENT在simpledll.cpp中定义
  6. #ifdef DLL_IMPLEMENT
  7. #define DLL_API __declspec(dllexport)
  8. #else
  9. #define DLL_API __declspec(dllimport)
  10. #endif
  11. namespace zdd
  12. {
  13. //导出类
  14. class DLL_API SimpleDll
  15. {
  16. public:
  17. SimpleDll();
  18. ~SimpleDll();
  19. int add(int x, int y); //简单方法
  20. static int sub(int x, int y);//静态方法
  21. int getConst(); //
  22. int getNum();
  23. private:
  24. void setNum(int n);
  25. int num;
  26. };
  27. //全局变量
  28. int DLL_API number;
  29. SimpleDll DLL_API sdd;
  30. //对于指针,下面两种用法没区别?
  31. SimpleDll DLL_API *psdd;
  32. SimpleDll *psdd1;
  33. //方法
  34. int DLL_API Add(int a, int b);
  35. SimpleDll *createClass()
  36. {
  37. return new SimpleDll;
  38. }
  39. /*
  40. //问题1:若这样使用,则出现如下错误:
  41. // error C2059: syntax error : '__declspec(dllexport)'
  42. // error C2143: syntax error : missing ';' before '{'
  43. // error : '__declspec(dllimport)'
  44. // error C2143: syntax error : missing ';' before '{'
  45. // error C2447: '{' : missing function header (old-style formal list?)
  46. //为什么?
  47. SimpleDll* DLL_API createClass1()
  48. {
  49. return new SimpleDll;
  50. }
  51. */
  52. /*
  53. //问题2:若这样使用,则出现如下错误:
  54. //Error 1   error C2491: 'zdd::createClass1' : definition of dllimport function not allowed usesimpledll
  55. //为什么?
  56. SimpleDll DLL_API * createClass2()
  57. {
  58. return new SimpleDll;
  59. }
  60. */
  61. //问题3:这样使用(实现在.cpp中),编译没有问题。
  62. //但在main中应用时回出现以下错误:
  63. // error LNK2019: unresolved external symbol "class zdd::SimpleDll * __cdecl zdd::createClass3(void)" (?createClass3@zdd@@YAPAVSimpleDll@1@XZ) referenced in function _main
  64. //该如何解决?
  65. SimpleDll *createClass3(); //先别这样用
  66. //全局方法加DLL_API和不加DLL_API时的区别
  67. int DLL_API getConst1();
  68. //int getConst2(); //不要这样使用
  69. //也不要这样用
  70. //否则当程序发布之后,如果只想通过更新.dll
  71. //来达到更新程序数据的目的,比如将此处的100更新成10.
  72. //通过下面的方法你是做不到的
  73. int getConst2()
  74. {
  75. return 100;
  76. //      return 10;
  77. }
  78. //也不要这样用,否则将出现如下错误
  79. //error C2491: 'zdd::getConst3' : definition of dllimport function not allowed
  80. /*
  81. int DLL_API getConst3()
  82. {
  83. return 100;
  84. }
  85. */
  86. //不要这样用,同理
  87. int others(int a)
  88. {
  89. return a+10;
  90. }
  91. }

simpledll.cpp文件:

  1. //------------------ simpledll.cpp ----------------
  2. //注意此处的宏定义需要写在#include "simpledll.h"之前
  3. //以完成在dll项目内部使用__declspec(dllexport)导出
  4. //在dll项目外部使用时,用__declspec(dllimport)导入
  5. #define DLL_IMPLEMENT
  6. #include "simpledll.h"
  7. namespace zdd
  8. {
  9. SimpleDll::SimpleDll()
  10. {
  11. }
  12. SimpleDll::~SimpleDll()
  13. {
  14. }
  15. int SimpleDll::add(int x, int y)
  16. {
  17. return x+y;
  18. }
  19. int SimpleDll::sub(int x, int y)
  20. {
  21. return x-y;
  22. }
  23. int SimpleDll::getConst()
  24. {
  25. return 10; //
  26. }
  27. void SimpleDll::setNum(int n)
  28. {
  29. num = n;
  30. }
  31. int SimpleDll::getNum()
  32. {
  33. return num;
  34. }
  35. extern int number = 5;
  36. int Add(int a, int b)
  37. {
  38. return a+b;
  39. }
  40. SimpleDll *createClass3()
  41. {
  42. return new SimpleDll;
  43. }
  44. int getConst1()
  45. {
  46. return 100;
  47. //return 10;
  48. }
  49. /*
  50. //error
  51. extern int getConst2()
  52. {
  53. return 100;
  54. }
  55. */
  56. }

main.cpp文件:

  1. //------------------ main.cpp -------------------
  2. #include "simpledll.h"
  3. using namespace zdd;
  4. #include <iostream>
  5. using namespace std;
  6. int main(char argc, char**argv)
  7. {
  8. //
  9. cout << "----------------------" <<endl;
  10. SimpleDll sd;
  11. cout << "sd.add: 3+5=" << sd.add(3, 5)<<endl;
  12. cout << "sd.getConst(): "<<sd.getConst()<<endl;
  13. SimpleDll *psd = new SimpleDll;
  14. cout << "psd->add: 5+5=" << psd->add(5, 5)<<endl;
  15. cout << "psd->getConst(): "<<endl;
  16. cout << "----------------------" <<endl;
  17. cout << "SimpleDll::sub: 2-1=" << SimpleDll::sub(2,1)<<endl;
  18. cout << "----------------------" <<endl;
  19. cout << "zdd::number: "<<number<<endl;
  20. number = 10;
  21. cout << "changed zdd::number: "<<number<<endl;
  22. cout << "----------------------" <<endl;
  23. cout << "sdd.add: 6+8=" << sdd.add(6,8)<<endl;
  24. cout << "psdd->add: 6+8=" <<psdd->add(6,8)<<endl;
  25. cout << "psdd1->add: 6+8=" <<psdd1->add(6,8)<<endl;
  26. cout <<endl;
  27. cout << "sdd.getConst(): "<<sd.getConst()<<endl;
  28. cout << "psdd.getConst(): "<<psdd->getConst()<<endl;
  29. cout << "psdd1.getConst(): "<<psdd1->getConst()<<endl;
  30. cout << "----------------------" <<endl;
  31. cout << "zdd::Add: 7+8="<<Add(7,8)<<endl;
  32. cout << "----------------------" <<endl;
  33. SimpleDll *p = createClass();
  34. cout << "create->add: 2+3=" <<p->add(3,2)<<endl;
  35. cout << "create->getConst(): "<<p->getConst()<<endl;
  36. cout << "----------------------" <<endl;
  37. //  SimpleDll *p3 = createClass3();
  38. //  cout << "create3->add: 2+3=" <<p3->add(3,2)<<endl;
  39. //  cout << "create3->getConst(): "<<p3->getConst()<<endl;
  40. //  cout << "----------------------" <<endl;
  41. cout << "----------------------" <<endl;
  42. //请别在你的应用程序中使用getConst2
  43. cout << "DLL_API getConst1: "<<getConst1()<<endl;
  44. cout << "        getConst2: "<<getConst2()<<endl;
  45. //  cout << "DLL_API getConst3: "<<getConst3()<<endl;
  46. cout << "----------------------" <<endl;
  47. //  cout << "others: " << others(6)<<endl;
  48. //  cout << "others: " << others(16)<<endl;
  49. //  cout << "----------------------" <<endl;
  50. cout << "please press Enter exit."<<endl;
  51. getchar();
  52. return 0;
  53. }

运行结果为:

  1. ----------------------
  2. sd.add: 3+5=8
  3. sd.getConst(): 10
  4. psd->add: 5+5=10
  5. psd->getConst():
  6. ----------------------
  7. SimpleDll::sub: 2-1=1
  8. ----------------------
  9. zdd::number: 5
  10. changed zdd::number: 10
  11. ----------------------
  12. sdd.add: 6+8=14
  13. psdd->add: 6+8=14
  14. psdd1->add: 6+8=14
  15. sdd.getConst(): 10
  16. psdd.getConst(): 10
  17. psdd1.getConst(): 10
  18. ----------------------
  19. zdd::Add: 7+8=15
  20. ----------------------
  21. create->add: 2+3=5
  22. create->getConst(): 10
  23. ----------------------
  24. ----------------------
  25. DLL_API getConst1: 100
  26. getConst2: 100
  27. ----------------------
  28. please press Enter exit.

可将生成的可执行文件和应用程序拷出到同一目录下,通过更改方法getConst1,getConst2,体会dllexport和dllimport的作用。

代码中提出的几个问题方法,暂时无解,暂不使用。
 
源码:
 
参考资料:

vs2010创建和使用动态链接库(dll)的更多相关文章

  1. VS2010创建和调用动态链接库

    当我们开发一个产品的时候,我们并不想把源码公布给对方,除了给对方提供exe可执行文件外,我们还可以生成动态链接库,供程序调用,方便二次开发. 下面我将简单梳理一下如何创建和调用动态链接库,方便大家程序 ...

  2. C# 创建和引入动态链接库dll文件

    一.创建动态链接库dll文件 新建 -> 项目->类库 名称为:dlltest 添加函数:消息框弹出消息 using System.Collections.Generic; using S ...

  3. vs2010 C++创建和使用动态链接库(dll)

    一.用C++创建动态链接库项目:  1.打开Microsoft Visual Studio 2010,选择File->New->Project.  2.在NewProject中选择Inst ...

  4. 创建一个动态链接库 (DLL),使用VS2010

    在本演练中,您将创建一个动态链接库 (DLL),其中包含可供其他应用程序使用的有用例程.使用 DLL 是一种重用代码的绝佳方式.您不必在自己创建的每个程序中重新实现这些例程,而只需对这些例程编写一次, ...

  5. 【转载】创建和使用动态链接库 (C++)

    原文:http://blog.csdn.net/handforcpp/article/details/3478254 也可参考MSDN: 演练:创建和使用动态链接库 (C++) 我们将创建的第一种类型 ...

  6. 演练:创建和使用动态链接库 (C++)

    我们将创建的第一种类型的库是动态链接库 (DLL). 使用 DLL 是一种重用代码的绝佳方式. 您不必在自己创建的每个程序中重新实现同一例程,而只需对这些例程编写一次,然后从需要该功能的应用程序引用它 ...

  7. VS2010创建动态链接库(DLL)的方法

    1.第一步创建WIN32项目,选择DLL 2.第二步,创建你自己的DLL CPP文件和头文件,下面以两个简单的加减法函数为例子导出 然后编译生成即可.DLL文件在Debug或Release目录中 .d ...

  8. VS2010编写动态链接库DLL及单元测试用例,调用DLL测试正确性

    转自:http://blog.csdn.net/testcs_dn/article/details/27237509 本文将创建一个简单的动态链接库,并编写一个控制台应用程序使用该动态链接库,该动态链 ...

  9. VS2010编写动态链接库DLL和单元测试,转让DLL测试的正确性

    本文将创建一个简单的动态库-link,谱写控制台应用程序使用该动态链接库,该动态链接库为"JAVA调用动态链接库DLL之JNative学习"中使用的DLL,仅仅是项目及文件名不同. ...

随机推荐

  1. JLabel跟label

  2. WildFly 9.0.2+mod_cluster-1.3.1 集群配置

    一.配置背景 最近使用WildFly 9.0.2作为中间件开发系统,给客户不熟的时候需要使用集群来进行负载均衡,一开始想到是使用Nginx.但是只通过Nginx使用 ip_hash 模式没有做到ses ...

  3. aptitude

    aptitude比apt-get 要好用.是 Debian 及其衍生系统中功能极其强大的包管理工具.与 apt-get 不同的是,aptitude在处理依赖问题上更佳一些.举例来说,aptitude在 ...

  4. ACTIVEX 重新安装与卸载

    1.卸载工具 SREngLdr.EXE,打开后执行 系统修复->浏览器加载项,找到对应的ACTIVEX,点击删除.OK 2.开发人员如遇到ACTIVEX版本更新.可在OBJECT 里加入更高版本 ...

  5. Asp.net笔记(原创)

    Repeater控件的使用:<asp:Label ID="Label1" runat="server" Text='<%#Eval("na ...

  6. JAVA中实现百分比

    import java.text.NumberFormat; public class TeachYou { public static void main(String[] args) { //这里 ...

  7. 使用hwclock同步RTC(硬件时钟)和OS Clock(操作系统时钟)

    Linux下面有个命令叫做hwclock,其主要的功能是用来在RTC和操作系统之间进行时钟同步.既可以将RTC的时钟同步到操作系统,也可以在通过hwclock将当前系统时间.Internet时间.本地 ...

  8. C++里容易忽视却不能忽视的

    1 define 只是简单地文本替换. 2 每个机器的字长不同. 3 每个类型在不同的机器上,所占用的内存空间不同. 4 每个机器内部的字节大小端不同. 5 并不是所有的编译器或机器都支持最新的C++ ...

  9. hibernate中fetch lazy

    join 查询的时候,是用一条语句查处所有记录,包括关联表记录, select查出的是N+1条记录,两个都是差不多的,但是如果用了lazy=true,延迟加 载的话,select在查询时只会查出主表记 ...

  10. 深入了解relative

    1.relative是自身定位,距原本位置的偏移 2.无侵入布局: 挪动位置,原本位置还在占据,并不会影响其他元素的布局   应用: 实现鼠标拖拽,比自身api好用 3.top/bottom 和 le ...