vs2010创建和使用动态链接库(dll)

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

本文包含以下内容:

创建动态链接库项目

向动态链接库添加类

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

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

更丰富的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的作用。

代码中提出的几个问题方法,暂时无解,暂不使用。
 
源码:
 
参考资料:
上一篇:【STL】关联容器 — hash_set


下一篇:使用autopep8自动规范化python3代码