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

***************************************************

更多精彩,欢迎进入:http://shop115376623.taobao.com

***************************************************


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

本文包含以下内容:

1、创建动态链接库项目

2、向动态链接库添加类

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

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

5、更丰富的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 WizardOverview对话框中点击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:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //------------------ simpledll.h ----------------  
  2.   
  3. #pragma once;  
  4.   
  5. //该宏完成在dll项目内部使用__declspec(dllexport)导出  
  6. //在dll项目外部使用时,用__declspec(dllimport)导入  
  7. //宏DLL_IMPLEMENT在simpledll.cpp中定义  
  8. #ifdef DLL_IMPLEMENT  
  9. #define DLL_API __declspec(dllexport)  
  10. #else  
  11. #define DLL_API __declspec(dllimport)  
  12. #endif  
  13.   
  14. namespace zdd  
  15. {  
  16.     //导出类  
  17.     class DLL_API SimpleDll  
  18.     {  
  19.     public:  
  20.         SimpleDll();  
  21.         ~SimpleDll();  
  22.   
  23.         int add(int x, int y); //简单方法  
  24.     };  
  25. }  

源文件simpledll.cpp:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //------------------ simpledll.cpp ----------------  
  2.   
  3. //注意此处的宏定义需要写在#include "simpledll.h"之前  
  4. //以完成在dll项目内部使用__declspec(dllexport)导出  
  5. //在dll项目外部使用时,用__declspec(dllimport)导入  
  6. #define DLL_IMPLEMENT   
  7.   
  8. #include "simpledll.h"  
  9.   
  10. namespace zdd  
  11. {  
  12.     SimpleDll::SimpleDll()  
  13.     {  
  14.   
  15.     }  
  16.   
  17.     SimpleDll::~SimpleDll()  
  18.     {  
  19.   
  20.     }  
  21.   
  22.     int SimpleDll::add(int x, int y)  
  23.     {  
  24.         return x+y;  
  25.     }  
  26. }  

4、完成后点击Build->Build Solution,生成解决方案。可在~zdddll\Debug下查看生成的simpledll.libsimpledll.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 WizardOverview对话框中点击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添加内容。如下所示:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //------------------ main.cpp -------------------  
  2. #include "simpledll.h"  
  3. using namespace zdd;  
  4.   
  5. #include <iostream>  
  6. using namespace std;  
  7.   
  8. int main(char argc, char**argv)  
  9. {  
  10.     //  
  11.     cout << "----------------------" <<endl;  
  12.     SimpleDll sd;  
  13.     cout << "sd.add: 3+5=" << sd.add(3, 5)<<endl;  
  14.     cout << "sd.getConst(): "<<sd.getConst()<<endl;  
  15.   
  16.     SimpleDll *psd = new SimpleDll;  
  17.     cout << "psd->add: 5+5=" << psd->add(5, 5)<<endl;  
  18.     cout << "psd->getConst(): "<<endl;  
  19.   
  20.     cout << "----------------------" <<endl;  
  21.     cout << "please press Enter exit."<<endl;  
  22.     getchar();  
  23.     return 0;  
  24. }  

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运行结果如下:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. 3+5=8  
  2. 5+5=10  

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

simpledll.h文件:

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

simpledll.cpp文件:

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

main.cpp文件:

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

运行结果为:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  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.   
  16. sdd.getConst(): 10  
  17. psdd.getConst(): 10  
  18. psdd1.getConst(): 10  
  19. ----------------------  
  20. zdd::Add: 7+8=15  
  21. ----------------------  
  22. create->add: 2+3=5  
  23. create->getConst(): 10  
  24. ----------------------  
  25. ----------------------  
  26. DLL_API getConst1: 100  
  27.         getConst2: 100  
  28. ----------------------  
  29. please press Enter exit.  

可将生成的可执行文件和应用程序拷出到同一目录下,通过更改方法getConst1,getConst2,体会dllexport和dllimport的作用。
代码中提出的几个问题方法,暂时无解,暂不使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458967.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

magenta内核与linux,谷歌将推出新操作系统Fuchsia:Magenta语言为内核

谷歌现在研发出来并且推出使用的系统有Chrome OS、Android和Chromecasts&#xff0c;这三者在操作系统的市场中占得份额很高&#xff0c;但是好像谷歌对此并不满意&#xff0c;因为有相关消息显示&#xff0c;谷歌正在研发新的操作系统Fuchsia&#xff0c;该系统采用Magenta语言…

BZOJ 1968: [Ahoi2005]COMMON 约数研究 水题

1968: [Ahoi2005]COMMON 约数研究 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id1968 Description Input 只有一行一个整数 N&#xff08;0 < N < 1000000&#xff09;。 Output 只有一行输出&#xff0c;为整数M…

VC内存对齐准则(Memory alignment)

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** 本文所有内容在建立在一个前提下&#xff1a;使用VC编译器。着重点在于&#xff1a;VC…

mysql 主主互备实现

今天星期天&#xff0c;么事就写个MYSQL的主主架构的博客&#xff0c;原理如下图&#xff0c;不是我画的网上找的。主机作用操作系统mysql版本对应IPvip数据库mysqlA(主)centos6.4mysql 5.5.48192.168.48.129192.168.48.126mysqlB(备)centos6.4mysql 5.5.48192.168.48.132一&am…

动手实践 Linux VLAN - 每天5分钟玩转 OpenStack(13)

本节我们来看如何在实验环境中实施和配置如下 VLAN 网络 配置 VLAN 编辑 /etc/network/interfaces&#xff0c;配置 eth0.10、brvlan10、eth0.20 和 brvlan20。 下面用 vmdiff 展示了对 /etc/network/interfaces 的修改 重启宿主机&#xff0c;ifconfig 各个网络接口 用 brct…

Socket的3次握手链接与4次断开握手

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** 连接握手&#xff1a; 1.客户端发送建立连接请求 &#xff08;发送请求&#xff09;2.…

Linux桌面需要强制访问控制,RHCSA 系列(十三): 在 RHEL 7 中使用 SELinux 进行强制访问控制...

RHCSA 认证&#xff1a;SELinux 精要和控制文件系统的访问尽管作为第一级别的权限和访问控制机制是必要的&#xff0c;但它们同样有一些局限&#xff0c;而这些局限则可以由安全增强 Linux(Security Enhanced Linux&#xff0c;简称为 SELinux)来处理。这些局限的一种情形是&am…

使用canvas实现擦玻璃效果

体验效果:http://hovertree.com/texiao/html5/25/效果图&#xff1a;代码如下&#xff1a; <!DOCTYPE html> <html> <head lang"zh"> <meta name"viewport" content"initial-scale1.0, maximum-scale1.0, user-scalableno, widt…

[转]opencv学习资料

转自&#xff1a;http://blog.csdn.net/poem_qianmo/article/details/20537737 1&#xff1a;Mat imread(const string& filename, intflags1 ); eg: Mat image0imread("dota.jpg",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);//载入最真实的图像 ge1i…

jQuery动态设置样式List item

前段时间&#xff0c;Insus.NET有修改一个功能《激活当前视图菜单高亮呈现》http://www.cnblogs.com/insus/p/5287093.html 今天Insus.NET想改用另外一个方法来实现&#xff0c;使用jQuery。在ASP.NET MVC 环境实现&#xff1a; 代码&#xff1a; <ul><li><a hr…

linux telnet 权限,允许telnet 通过root用户进行访问

允许telnet 通过root用户进行访问RHEL6:[rootclovem ~]# yum install telnet-server -y //安装telnet服务端[rootclovem ~]# cat /etc/xinetd.d/telnet //开启telnet的托管服务# default: on# description: The telnet server serves telnet sessions; it uses \#unencrypt…

TOUGHRADIUS 项目介绍

2019独角兽企业重金招聘Python工程师标准>>> TOUGHRADIUS 项目介绍 ToughRADIUS是一个开源的Radius服务软件&#xff0c;采用于 Apache License 2.0 许可协议发布&#xff0c;从创立之日起&#xff0c;他的宗旨就是服务于中小微ISP&#xff0c;让运营变得更简单。 T…

转:Jmeter 用户思考时间(User think time),定时器,和代理服务器(proxy server)...

在负载测试中需要考虑的的一个重要要素是思考时间&#xff08;think time&#xff09;&#xff0c; 也就是在两次成功的访问请求之间的暂停时间。 有多种情形挥发导致延迟的发生&#xff1a; 用户需要时间阅读文字内容&#xff0c;或者填表&#xff0c;或者查找正确的链接等。未…

linux sql语句传参数,Linux/Unixshell参数传递到SQL脚本

在数据库运维的过程中&#xff0c;Shell 脚本在很大程度上为运维提供了极大的便利性。而shell 脚本参数作为变量传递给SQL以及SQL脚本也是DB在数据库运维的过程中&#xff0c;Shell 脚本在很大程度上为运维提供了极大的便利性。而shell 脚本参数作为变量传递给SQL以及SQL脚本也…

Myeclipse5.5获取注册码

2019独角兽企业重金招聘Python工程师标准>>> import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class MyEclipseGen {private static final String LL "Decompiling this copyrighted software is a vi…

对互联网中常见地图的坐标系探讨

文章版权由作者李晓晖和博客园共有&#xff0c;若转载请于明显处标明出处&#xff1a;http://www.cnblogs.com/naaoveGIS/。 1.背景 目前项目中使用百度地图、高德地图、谷歌中国地图、天地图的需求越来越多&#xff0c;这里我跟大家一起对各地图使用的坐标系做一个简单的探讨。…

讯飞输入法有没有Linux,Debian testing 安装讯飞输入法 - Linux系统与应用 - LinuxApp - 水木社区...

突然发现Deepin发行版带有讯飞输入法&#xff0c;于是折腾了一会&#xff0c;安装好了这个输入法&#xff0c;现把安装过程分享如下&#xff1a;软件包的依赖&#xff1a;Package: iflyimeVersion: 0.9.962Section: develPriority: optionalArchitecture: amd64Depends: libboo…

HTTP必知必会

2019独角兽企业重金招聘Python工程师标准>>> HTTP消息HTTP请求消息HTTP响应消息消息首行请求行响应行消息头部请求头请求头消息正文请求正文响应正文Web服务器把接收到的HTTP请求消息封装成request对象&#xff0c;作为service的参数传入service函数&#xff0c;ser…

更新10_linux,时隔十年,QQ更新了Linux版本

昨天1024程序员节&#xff0c;QQ悄悄地更新了QQ for Linux&#xff0c;也许是给各位一个惊喜吧。官网及其的简陋。和一个Word文档似的。十年一更&#xff0c;有网友称&#xff0c;瞬间回到QQ2006&#xff0c;确实界面功能有些落后&#xff0c;相信QQ可以跟上潮流的&#xff0c;…

C语言里if语句变量作为判断条件,C语言教学(九-上)if else判断语句

原标题&#xff1a;C语言教学(九-上)if else判断语句今天讲if else判断语句&#xff0c;简单理解就是进行条件判断&#xff0c;如果条件达到则执行if 里或else里的语句。先来看if。if的写法和for差不多,就是不用括号里的两个分号&#xff0c;if (条件) { }&#xff0c;if加括号…