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,一经查实,立即删除!

相关文章

通用二进制

通用二进制 通用二进制&#xff08;Universal binary&#xff09;是苹果电脑公司提出的一种程序代码&#xff0c;使程序能以本地程序的形式运行在使用PowerPC或者英特尔微处理器&#xff08;x86&#xff09;的麦金塔电脑上&#xff0c;在同一个程序包中同时为两种架构提供最理想…

Python~win32com~Excel

import win32com.client#wwin32com.client.Dispatch("Word.Application") #w.Visible1owin32com.client.Dispatch("Excel.Application") o.Visible1 o.Workbooks.Add() o.Cells(1,1).Value"Hello"转载于:https://www.cnblogs.com/lynclynn/p/530…

linux显示光盘命令行,使用wodim在命令行下烧录光盘

使用wodim在命令行下烧录光盘发布时间:2009-02-27 16:23:11来源:红联作者:zhania作者&#xff1a;linuxtoy出自http://linuxtoy.org/archives/burning-cd-with-wodim.html我们以前介绍的 Linux 光盘烧录工具多为图形化的程序&#xff0c;今天来看看如何使用 wodim 在命令行下烧…

Android(java)学习笔记144:网络图片浏览器的实现(ANR)

1.我们在Android下&#xff0c;实现使用http协议进行网络通信&#xff0c;请求网络数据。这里是获取网络上的图片信息&#xff0c;让它可以显示在手机上&#xff1b; 但是我们这个手机连接网络是很费时间&#xff0c;如果我们在主线程&#xff08;UI线程&#xff09;中写这个网…

DLL导出函数名称改编的解决方法

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** 1.DLL编译后导出函数名称改变 在编写一个DLL后&#xff0c;为了能被别的程序调用&…

组合自定义控件的步骤详解

Android 步骤&#xff1a; 1 自定义组合控件的布局settint_view.xml<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:orientation"vertical"and…

linux如何建立隐藏目录,【Linux】文件与目录的默认权限与隐藏权限

01. 文件默认权限&#xff1a;umask文件的权限可以使用chmod来改变&#xff0c;但是我们默认创建文件的权限是什么&#xff1f;那就是与umask这个有关了。下来我们学习这个指令1.1 简单使用umask[rootiZbp13q6hd8z3xaagcmz6gZ /]# umask0022[rootiZbp13q6hd8z3xaagcmz6gZ /]# u…

Servlet和JSP学习指导与实践(二):Session追踪

前言&#xff1a; web应用中经常需要对某些有用的信息进行存储或者附加一些信息。本文主要介绍session&#xff0c;即“会话”跟踪的几种不同方式~ ----------------------------4种管理session的方式&#xff1a; 1.重写url 通过在请求的url后面追加参数信息进行会话跟踪。如&…

数据存储和界面展示(二)

#测试 黑盒测试 测试逻辑业务 白盒测试 测试逻辑方法 根据测试粒度 方法测试&#xff1a;function test 单元测试&#xff1a;unit test 集成测试&#xff1a;integration test 系统测试&#xff1a;system test 根据测试暴力程度 冒烟测试&#xff1a;smoke test 压力测…

linux在A目录下创建B文件,Linux课程---5、常用文件命令和目录命令(创建文件命令)...

Linux课程---5、常用文件命令和目录命令(创建文件命令)一、总结一句话总结&#xff1a;touch file11、管道符|有什么用&#xff1f;将前一个命令的结果作为后一个命令的输入&#xff1a;比如查看文件前3行&#xff1a;cat file1 | head -32、linux下如何复制粘贴命令是什么&…

window 系统上传文件到linux 系统出现dos 格式换行符

Windows里的文件在Unix/Mac下打开的话&#xff0c;在每行的结尾可能会多出一个^M符号&#xff0c;Unix/Mac系统下的文件在Windows里打开的话&#xff0c;所有文字会变成一行&#xff0c;所以为了避免这种情况的发生&#xff0c;我们可以在linux系统内转换格式 Centos系列可以直…

#pragma once与 #ifndef的区别

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** 为了避免同一个文件被include多次 1 #ifndef方式2 #pragma once方式 在能够支持这…

android学习者优秀网址推荐

非常漂亮的android UI库集合&#xff0c;别人整理的&#xff0c;如果感觉不错&#xff0c;赶快收藏吧&#xff01;&#xff01; https://github.com/wasabeef/awesome-android-ui https://github.com/Trinea/android-open-project android中文社区网 http://www.android-studio…

linux while read文件,linux shell脚本用while read逐行读取文本的问题

问题:我现在是想用一个脚本获取一定列表服务器的运行时间。首先我建立一个名字为ip.txt的IP列表(一个IP一行)&#xff0c;再建好密钥实现不用密码直接登录。然后写脚本如下&#xff1a;#!/bin/bashwhile read ips;doecho $ips;done < ip.txt脚本实现了逐行读取列表中的IP&am…

常用字符串处理函数汇总

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** (一)strcmp函数 strcmp函数是比较两个字符串的大小,返回比较的结果。一般形式是&…

兼容性记录-class属性

getAttribute获得class属性时,IE6,IE7的传參是className,IE7和现代游览器都是class全部游览器DOMElement均有的className属性,其在IE各版本号下的均表现良好返回属性class值的字符串此外html5中DOMElement有个classList属性,它返回一个类型为DOMTokenList的对象,它当中有非常多…

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…

[redis设计与实现][7]基本数据结构——对象

Redis对基础数据类型进行了封装&#xff0c;构建出上层的对象系统&#xff0c;这个系统包含&#xff1a;字符串对象、列表对象、哈希对象、集合对象和有序集合对象。 Redis对象结构&#xff1a; [cce lang”c”] typedef struct redisObject { //类型 unsigned type:4; //编码 …