VC6.0如何创建以及调用动态链接库实例详解

小弟在公司的职责,在上篇博客中已经简约介绍。这边博客主要介绍技术的应用而不在细究原理。因为公司项目着急,出结果要紧,并且咱也不是专注搞研究的,所以,基本懂了原理后,直接上手工作,搞出demo来最好。

至于公司工作情况,今天暂且略过,当然也不是一两句能够表达清楚的。后面会有相应的工作总结,敬请期待……

现在,废话少说,直奔主题——VC6.0中创建动态链接库。
作为客户与后台的中介,为了更好的调节两方的关系,我明智滴选择了webservice以及动态链接库。在与客户c++使动态链接库方式,而与后台java,使用webservice来交流沟通。
既然有了动态链接库,肯定大家会想到静态链接库。呵呵,这个是相对的。那这两者有什么区别呢?那又为什么选择了动态链接库呢?
静态链接库:是把lib文件也打包到了exe文件中。
动态链接库:没有把lib文件打包到exe文件中,若是使用,则直接加载卸载相应的dll文件。
并且,静态链接库中不允许包含静态链接库和动态链接库,而动态链接库中是允许包含静态链接库和动态链接库的。因为小弟封装的dll中是调用客户的dll,并且有可能包含另外自己的动态链接库。
鉴于此,小弟选择了动态链接库。
还有一点是,动态链接库,也是分为三种情况的。一是非MFC的dll(也就是控制台的dll),二是常规的MFC的dll(其中又分静态的dl和共享的dll),三是扩展的MFC 的dll。并且MFC的dll可以被MFC程序或者控制台程序调用。
因为小弟封装的dll,需要供MFC程序调用,所以选择使用了MFC常规的dll。并且使用控制台程序做测试。
首先,在新建工程中选择MFC AppWizard (dll)
然后在头.h文件中,声明被外界调用的函数


代码如下:

extern "C" _declspec(dllexport) char* queryFunctionByFID(char* funcId);

声明后,在cpp文件中,实现此函数。


代码如下:

char* queryFunctionByFID(char* funcId)
{
…………………………
具体的操作实现}

编译,build生成。OK,在Debug下生成相应的dll,至此动态链接库生成了。然后程序就可以直接使用此dll文件了。
然后呢。把dll文件copy到相应的测试dll程序(调用dll的程序)下。使用方式如下:
我测试dll程序中,是使用的控制台程序,这样简单方便,当然使用MFC程序也可以。
比如:我们新建一个控制台程序,然后在main方法中,写如下:


代码如下:

//声明函数指针 写明函数参数个数,参数类型以及返回值类型
typedef char* (* queryFunctionByFID)(char*);
//加载动态链接库,返回DLL文件的句柄
HINSTANCE hDLL=NULL;
//加载动态链接库,dll名称要与刚才生成的dll名称保持一致。
hDLL=LoadLibrary("IProcessInstIn.dll");
queryFunctionByFID saveProcess=NULL;
//加载动态链接库中相应的函数
saveProcess=(queryFunctionByFID)GetProcAddress(hDLL,"queryFunctionByFID");
//真正的调用相应的函数
cout<<"结果是:"<<saveProcess("dd");
//调用完毕后释放资源
FreeLibrary(hDLL);

每一句的作用,注释已经表达清楚。若是有不懂的,可以联系我,互相交流一下。
其实,动态链接库,类似我们VS中的dll,只不过,当时只要把dll引用到相应的程序,然后直接可以使用。而在此,是我们手动加载,连接,释放dll。使用这种方式的动态链接库,我们可以很随意在我们程序中的任何地方都可以使用我们想调用的函数。
只要我们遵守了“加载,LoadLibrary——GetProcAddress——FreeLibrary”原则即可。使用相当方便。即可解脱了两者之间耦合的困扰,又可以加载释放方便。
调用静态链接库的做法如下
第一:把lib文件和dll文件两个文件全部放在客户端下,调用动态链接库时,只需要dll文件。
第二:在客户端中需要新建头文件,类似dll中的导出函数的头文件。
第三:在客户端调用dll文件中(cpp文件),添加预指令,也就是把lib文件显式加载进来。
如:#pragma comment (lib,"IProcessInstIn.dll")
第四:在button事件下,直接调用相应的方法。
如:cout<<"结果是:"<<queryFunctionByFID(相应的参数);
总之,调用静态链接库,相对于来说,比较简单,只要把相应的文件加载进来后,直接调用方法即可。但是调用动态链接库相对来说,比较灵活,何时使用何时加载,不使用了直接卸载即可。
任何事物都有优缺点,我们呢,就是充分利用他们的优点,在不同的场合不同的需求下使用不同的方式。
刚才我们在生成dll时,使用Debug版本下的dll,既然有可以选择Debug版本,根据我们的思维,肯定会想到,存在另外的版本。下篇博客中,我们会介绍一下Debug版本下的动态链接库和另一个版本Release版本下的动态链接库的区别,以及何时何地选择何种版本。

(0)

相关推荐

  • 在Visual Studio使用C++开发Metro应用

    Visual Studio 11 消费者预览版支持使用 C++ 创建 Metro 风格的应用程序,这对广大本地应用开发者来说是一个大消息.这里我们来创建一个非常简单的 Metro 应用. 启动 Visual Studio 并通过 Visual C++>Windows Metro Style>Blank Application 模板创建一个项目.  "Hello world" 打开 BlankPage.xaml 文件,滚动到代码底部并定位 Grid 元素,然后插入一个 Tex

  • 在Visual Studio中用C++语言创建DLL动态链接库图文教程

    什么是DLL(动态链接库)? DLL是一个包含可由多个程序同时使用的代码和数据的库.例如:在Windows操作系统中,Comdlg32 DLL执行与对话框有关的常见函数.因此,每个程序都可以使用该DLL中包含的功能来实现"打开"对话框.这有助于促进代码重用和内存的有效使用.这篇文章的目的就是让你一次性就能了解和掌握DLL. 为什么要使用DLL(动态链接库)? 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可以将它构造成相对独立的功能模块并在之后的项目中重复

  • VC6.0代码自动提示 VC6.0在win7环境下代码提示智能化

    作为程序猿的你,是否已经喜欢或习惯依赖IDE开发环境呢.作为Java程序猿,我还是蛮深深的依赖Java IDE开发环境滴,比如Eclipse或MyEclipse. 有了IDE环境,即使你想不起方法全名,只要知道某个前缀,或哪怕在提示列表中,一一查询,也可以找到自己想找的方法或属性.但是,若是IDE不这么智能,那你是否还能胜任吗? 目前小弟就遇到此情况.VC6.0环境,o(︶︿︶)o 唉,还是不能跟Eclispe相媲美的,也许是对VC6.0不熟悉,对Eclispe相对于熟悉,所以VC6.0使用起来

  • 在Visual Studio上构建C++的GUI框架wxWidgets的开发环境

    本文使用的Unicode+DLL+Debug的方式,因为不想最后生成的exe文件太大. 环境搭建步骤如下: 1.下载wxWidgets包: 登录wxWidgets的下载页面:http://www.wxwidgets.org/downloads 下载最新的Stable Release稳定版,我这里用旧的2.8.12版作演示. 2.将wxMSW-2.8.12.zip解压到D盘根目录下. 转到D:\wxMSW-2.8.12\build\msw目录,用VS2005打开wx.dsw,会有提示转换项目: 选

  • Microsoft Visual C++ 程序的部署方法

    1. 用Microsoft Visual C++ 6.0编译的程序,或者发布在Windows 2000/NT/ME/98 系统单纯通过拷贝MSVCRxx.DLL文件到应用程序目录或system32目录即可 2. 用Visual Studio 2005以上编译的程序,且发布在Windows XP及以上系统为了减少DLL引发的配置问题(DLL hell),C和C++运行时由并行 (Side-by-Side) 程序集实现,单纯通过拷贝MSVCRxx.DLL并不足以在非开发环境正常运行程序,必须通过一个

  • VC6.0打开文件以及向工程中添加文件时程序崩溃自动退出解决方法

    换了一台电脑,vc6.0程序中,点击打开文件以及向工程中添加文件时,程序竟然崩溃自动退出了. 不知什么原因,安装相同的vc程序,本本竟然出现此缘故.但是这个操作又是自己经常用到的,所以不得不解决. 与上一台电脑不同的是,此电脑是win7系统,而上一个则是xp系统.此电脑office是2010版本,而上一个则是WPS:于是乎,在网上查资料,来解决. 看到网上也有类似的问题,有的说是win7系统原因,有的说是office2007版本缘故,有的说是viso缘故.总之,这几种说法,我都符合.win7系统

  • Microsoft Visual C++ 6.0开发环境搭建教程

    上一篇演示的是如何安装VS2010,本文演示的是如何安装Microsoft Visual C++ 6.0 简称VC6. 有同学经常VC6都是很古董的版本了,为啥他还存在,不得不说VC6是微软一个很经典的版本. 现在很多公司都还是采用这个开发环境,不过大多数同学们的系统可能已经是win7或者win8.1了,导致VC6奔溃. 本文演示的VC++6.0绿色版本不存在这样的问题. 1.绿色版,先解压缩VC++6.0绿色版, 2.然后打开  运行.bat 3.输入项目名称 4.选择hello world

  • VC6.0如何创建以及调用动态链接库实例详解

    小弟在公司的职责,在上篇博客中已经简约介绍.这边博客主要介绍技术的应用而不在细究原理.因为公司项目着急,出结果要紧,并且咱也不是专注搞研究的,所以,基本懂了原理后,直接上手工作,搞出demo来最好. 至于公司工作情况,今天暂且略过,当然也不是一两句能够表达清楚的.后面会有相应的工作总结,敬请期待-- 现在,废话少说,直奔主题--VC6.0中创建动态链接库. 作为客户与后台的中介,为了更好的调节两方的关系,我明智滴选择了webservice以及动态链接库.在与客户c++使动态链接库方式,而与后台j

  • IOS 创建并发线程的实例详解

    IOS 创建并发线程的实例详解 创建并发线程 主线程一般都是处理UI界面及用户交互的事儿的.其他的事一般就要另外的线程去处理,如下载,计算等... 现在先简单创建3个线程,分别打印出1-1000,,为了方便,线程3就放在主线程中执行. - (void) firstCounter{ @autoreleasepool { NSUInteger counter = 0; for (counter = 0; counter < 1000; counter++){ NSLog(@"First Cou

  • mysql创建删除表的实例详解

    表的创建命令需要: 表的名称 字段名称 定义每个字段(类型.长度等) 语法 下面是通用的SQL语法用来创建MySQL表: CREATE TABLE table_name (column_name column_type); 现在,我们将在 test 数据库中创建以下表. create table tutorials_tbl( tutorial_id INT NOT NULL AUTO_INCREMENT, tutorial_title VARCHAR(100) NOT NULL, tuto

  • java中构造器内部调用构造器实例详解

    可能为一个类写了多个构造器,有时可能想在一个构造器里面调用另外一个构造器,为了减少代码的重复,可用this关键字做到这一点. public class Flower { private String string; private int age; public Flower() { // 先调用public Flower(String string, int age) this("leon", 120); // 先调用public Flower(String string, int

  • Python 调用Java实例详解

    Python 调用Java实例详解 前言: Python 对服务器端编程不如Java 所以这方面可能要调用Java代码 前提: Linux 环境  1 安装 jpype1 安装后测试代码: from jpype import * startJVM(getDefaultJVMPath(), "-ea") java.lang.System.out.println("Hello World") shutdownJVM() 2 调用非jdk的jar包, test.jar 包

  • vue.js2.0 实现better-scroll的滚动效果实例详解

    什么是 better-scroll better-scroll 是一个移动端滚动的解决方案,它是基于 iscroll 的重写,它和 iscroll 的主要区别在这里 .better-scroll 也很强大,不仅可以做普通的滚动列表,还可以做轮播图.picker 等等. <template> <div> <div class="goods"> <div class="menu-wrapper" ref="menuWr

  • Vue组件之间的参数传递与方法调用的实例详解

    目录 父组件向子组件 子组件调用父组件方法 其它组件间调用 补充: 父组件向子组件 1.父组件向子组件传参:父组件中的子组件标签中增加 :param="param" 子组件中增加 props 接受参数(注意props需要与data同级) props: { param: { type: Object } }, data() { return { ... } }, 2.父组件调用子组件方法:父组件中子组件的标签增加 ref="abc" 例如: <child ref

  • Android 调用WCF实例详解

    Android 调用WCF实例 1. 构建服务端程序 using System.ServiceModel; namespace yournamespace { [ServiceContract(Name = "HelloService", Namespace = "http://www.master.haku")] public interface IHello { [OperationContract] string SayHello(); } } namespa

  • MySQL存储过程的创建、调用与管理详解

    存储过程简介 为什么要用存储过程? MySQL5.0 版本开始支持存储过程. 大多数 SQL 语句都是针对一个或多个表的单条语句.并非所有的操作都那么简单.经常会有一个完整的操作需要多条语句才能完成. 存储过程简单来说,就是为以后的使用而保存的一条或多条 MySQL 语句的集合.可将其视为批处理文件.虽然他们的作用不仅限于批处理. 存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用. 存储过程的优点 通过把处理封装在容易使用的单元中,简化复杂的操作: 简化对变动的管理.如果表名.

  • 使用异步方式调用同步方法(实例详解)

    说明: .NET Compact Framework 中不支持异步委托调用,也就是 BeginInvoke 和 EndInvoke 方法. BeginInvoke 方法启动异步调用.该方法与您需要异步执行的方法具有相同的参数,还有另外两个可选参数.第一个参数是一个 AsyncCallback 委托,该委托引用在异步调用完成时要调用的方法.第二个参数是一个用户定义的对象,该对象将信息传入回调方法.BeginInvoke 会立即返回,而不等待异步调用完成.BeginInvoke 返回一个可用于监视异

随机推荐