Visual C++ 6.0静态、动态链接库
1.什么是静态连接库,什么是动态链接库 静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。静态链接库与静态链接库调用规则总体比较如下。
对于静态链接库(比较简单): 首先,静态链接库的使用需要库的开发者提供生成库的.h头文件和.lib文件。
生成库的.h头文件中的声明格式如下: extern "C" 函数返回类型 函数名(参数表); 在调用程序的.cpp源代码文件中如下:
#include "..\lib.h"
#pragma comment(lib,"..\\debug\\libTest.lib") //指定与静态库一起链接
第二,因为静态链接库是将全部指令都包含入调用程序生成的EXE文件中。因此如果用的是静态链接库,那么也就不存在“导出某个函数提供给用户使用”的情况,要想用就得全要!要不就都别要!:)
对于动态链接库: 动态链接库的使用,根据不同的调用方法,需要提供不同的资源:
1. 静态加载------程序静态编译的时候就静态导入dll,这样的话就需要提供给库使用者(C客户)如下文件:*.lib文件和.dll文件和*.h。其有2个坏处:
1 程序一开始运行就需要载入整个dll,无法载入程序就不能开始运行; 2 由于载入的是整个dll,需要耗费资源较多
其调用方法如下:
#include "..\lib.h"
#pragma comment(lib,"..\\debug\\libTest.lib")
但是这种方式的话可以调用Class method.
2.动态加载-----那么只需要提供dll文件。
因此调用程序若想调用DLL中的某个函数就要以某种形式或方式指明它到底想调用哪一个函数。但是无法调用Class method了。 如果要调用Dll中的function,需要经历3个步骤: Handle h=LoadLibrary(dllName) --> GetProcAddress(h,functionName) 返回函数指针,通过函指针调用其function-->FreeLibrary(h) 例如:Another.dll有一个int Add(int x,int y)函数。则完整的调用过程如下: typedef int (* FunPtr)(int,int);//定义函数指针
FunPtr funPtr; Handle h=LoadLibrary("Another.dll");
funPtr=(FunPtr)GetProcAddress(h,"Add");
funPtr(2,3);//2+3; FreeLibrary(h);
2.示例 示例之一: 静态链接库的创建过程: 例如:我们创建一个自定义字符串的类CHironString, 只需要在IDE里面添加class即可,然后program相应函数体 代码如下所示: SDLL.h文件 ------------------------------------------------------------------------ // HironString.h: interface for the CHironString class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C934C59__INCLUDED_) #define AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C934C59__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
class CHironString { private:
char* m_data; public: char * GetData(); CHironString(CHironString &other); int Length(); CHironString(); CHironString(char * str); CHironString& operator=(CHironString &other); virtual ~CHironString(); };
#endif // !defined(AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C934C59__INCLUDED_)
SDLL.CPP如下: -------------------------------------------------------------- // HironString.cpp: implementation of the CHironString class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "HironString.h"
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
CHironString::CHironString() { m_data=NULL; }
CHironString::CHironString(char * str) { int len=strlen(str); m_data=new char[len+1]; strcpy(m_data,str);
}
CHironString::~CHironString() { delete m_data; }
int CHironString::Length() { return strlen(m_data); }
CHironString::CHironString(CHironString &other) { int len=strlen(other.m_data)+1; m_data=new char[len]; strcpy(m_data,other.m_data); }
CHironString& CHironString::operator =(CHironString &other) { if(this==&other) return *this; if(m_data!=NULL) delete[] m_data; int len=strlen(other.m_data)+1; m_data=new char[len]; strcpy(m_data,other.m_data); return *this; }
char * CHironString::GetData() { return m_data; }
然后,将程序编译后生成sdll.lib。 客户调用:将CHironString.h和SDLL.lib发布给client,那么客户端就可以调用我们编写的静态链接库了。
示例之二: 动态链接库的创建
首先我们必须先注意到DLL内的函数分为两种: (1)DLL 导出函数,可供应用程序调用; (2)DLL 内部函数,只能在 DLL 程序使用,应用程序无法调用它们。
我们还是创建一个自定义的字符串处理类CHironString,不同之处其是一个动态链接库Dll。 动态链接库的export 需要在在相应的头文件中编写相应的MACRO MyDll.h:自定义了一些类(函数)export 宏(该文件由IDE自动生成)如下
------------------------------------------------------------------
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
这是导出类的宏定义,将导出类必须加上该宏,才能被导出。
此处的MYDLL_EXPORTS会出现在 project-->settings-->C/C++页面上的 PreProcessor definition中,这个MACRO表明其要定义一个导出宏
CHironString.h 自定义类头文件 ---------------------------------------------------------------- // HironString.h: interface for the CHironString class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_HIRONSTRING_H__518E9EC4_0837_4E45_9516_7D6A70CD3D0F__INCLUDED_) #define AFX_HIRONSTRING_H__518E9EC4_0837_4E45_9516_7D6A70CD3D0F__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "MyDll.h"
class MYDLL_API CHironString //加上MYDLL_API表明此为Export Class { private:
char* m_data; public: char * GetData(); CHironString(CHironString &other); int Length(); CHironString(); CHironString(char * str); CHironString& operator=(CHironString &other); virtual ~CHironString();
};
#endif // !defined(AFX_HIRONSTRING_H__518E9EC4_0837_4E45_9516_7D6A70CD3D0F__INCLUDED_)
CHironString.Cpp ------------------------------------------------------------
// HironString.cpp: implementation of the CHironString class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "HironString.h"
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
CHironString::CHironString() { m_data=NULL; }
CHironString::CHironString(char * str) { int len=strlen(str); m_data=new char[len+1]; strcpy(m_data,str);
}
CHironString::~CHironString() { delete m_data; }
int CHironString::Length() { return strlen(m_data); }
CHironString::CHironString(CHironString &other) { int len=strlen(other.m_data)+1; m_data=new char[len]; strcpy(m_data,other.m_data); }
CHironString& CHironString::operator =(CHironString &other) { if(this==&other) return *this; if(m_data!=NULL) delete[] m_data; int len=strlen(other.m_data)+1; m_data=new char[len]; strcpy(m_data,other.m_data); return *this; }
char * CHironString::GetData() { return m_data; }
经过compile之后,会生成MyDll.dll和MyDll.lib文件。
客户端的调用: 1.如果是静态加载,那么需要提供*.lib和*.h,运行时候需提供*.dll
2.如果是动态加载,只需要提供*.dll即可。
Visual C++ 6.0静态、动态链接库的更多相关文章
- 基于Visual C++6.0的DLL编程实现
整理自基于Visual C++6.0的DLL编程实现 本文通过通俗易懂的方式,全面介绍了动态链接库的概念.动态链接库的创建和动态链接库的链接,并给出个简单明了的例子,相信读者看了本文后,能够创建自己的 ...
- Microsoft Visual C++ 6.0预处理器参考手册
返回总目录 Microsoft Visual C++ 6.0 预处理器参考手册 目录引言........................................................ ...
- Visual Studio 写自己的动态链接库(DLL)
有些时候,我们想写自己的函数库以避免重复写代码,此文介绍如何使用Visual Studio编写自己的动态链接库. 0,实验环境说明: 集成开发环境:Visual Studio 10.0 操作系统: W ...
- 转 Visual C++6.0 与matlab联合编程(2)----Visual C++6.0 环境下编译和调试MEX文件
我的最初想法是利用matlab的mex命令调用C++程序生成动态链接库的,但是测试程序(文中另附)通过了,自己的实际应用程序却没有过.还是把方法贴在这儿,以便自己以后进行整理. http://shij ...
- C++高级编程2. 静态动态链接库
C++高级编程2. 静态动态链接库20131018 1.动态链接库和静态链接库的区别: 静态链接库就是把lib文件中用到的函数代码直接连接进目标程序,程序运行的时候不在需要其他的库文件:动态链接库是把 ...
- Visual C++ 6.0踩坑记录---在Win10下安装Visual C++ 6.0安装成功后点击“打开”按钮闪退问题
前言: 为了更好的学习C及C++,前段时间下载了Microsoft Visual C++ 6.0(以下简称VC6),原因是VC6具有查看反汇编代码.监视内存.寄存器等功能,并且因为本人正在学习滴水逆向 ...
- 微软Visual Studio Code 0.8.0发布,新增多种主题
月30日,Build 开发者大会上,正式宣布了 Visual Studio Code 项目;并将其定义为:一个运行于 Mac OS X.Windows和 Linux 之上的,针对于编写现代 Web 和 ...
- Microsoft Visual SourceSafe 6.0 无法关联项目
最近遇到Microsoft Visual SourceSafe 6.0 安装好以后, 无法关联项目,导致无法进行版本控制,研究以后,发现需要运行一个程序,在安装目录下 ..\Visual Source ...
- Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)
Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xamarin For iOS,最新版的已经把两个独立的插件合并为一个exe安装包了.为了区分 ...
随机推荐
- Debian8 加载NTFS 磁盘出错 解决方法
执行 ntfsfix /dev/sdb2 // sd* a代表第一块硬盘 b代表第2块硬盘 数字是分区号 执行后 就可以正常使用了.
- .NET的JSNO 序列化跟反序列化
由于本人最近在写webservice,之前一直都同通过AJAX,在服务端处理业务,但是最近需要写一些接口给其他人用,需要使用jsno的序列化与反序列化,什么是jsno就不多说,jsno的好处也不多说, ...
- Xcode6模拟器时BUG导致键盘无法弹出
Xcode 6.X版本可能会出现虚拟键盘无法调出,并在控制台出现如下提示:Can't find keyplane that supports type 5 for keyboard iPhone-Po ...
- sqlserver 大文件脚本执行
sqlserver2008中需要执行大文件的脚本,查询分析器中打不开,需要用到sql命令,开始使用osql命令,不过提示对应sqlserver2008中的驱动找不到(具体原因未分析-空闲时在处理),使 ...
- Java实战之04JavaWeb-03会话技术
一.会话技术简介 1.什么是会话,为什么需要会话技术? 会话:从打开一个浏览器,访问某个网站,到关闭这个浏览器的这个过程称为一次会话.http协议是状态的. 2.会话技术的分类 客户端存储技术:Coo ...
- UVALive 3027(并查集)
题意:某公司的各企业群要建立联系,I i j 表示企业i与企业j建立联系,并且以企业j为中心(并查集中的父亲)(企业j为暂时的中心企业),E i 表示查询企业 i 距离此时的中心企业的距离.各企业间的 ...
- 暑假集训(4)第三弹 -----递推(Hdu1799)
问题描述:还记得正在努力脱团的小A吗? 他曾经最亲密的战友,趁他绘制贤者法阵期间,暗中设下鬼打墙将小A 围困,并准备破坏小A正在绘制的法阵.小A非常着急.想阻止他的行动.而要阻止他,必须先破解鬼打墙. ...
- DirectSound学习(二)--流式缓冲区
使用流式缓冲方式播放波形音频文件比较复杂,主要原因是在只有一个缓冲区提供给用户的前提下,这个缓冲区在提供给声卡播放数据的同是还需要用户不断的定时向其中写入数据.要注意从缓冲区这时是一个环形缓冲区,声音 ...
- Kakfa揭秘 Day4 Kafka中分区深度解析
Kakfa揭秘 Day4 Kafka中分区深度解析 今天主要谈Kafka中的分区数和consumer中的并行度.从使用Kafka的角度说,这些都是至关重要的. 分区原则 Partition代表一个to ...
- .NET基础之自定义泛型
在.NET中泛型使用非常频繁,在控制台应用程序中,默认的引入了System.Collection.Generics名称空间,其中就提供了我们经常使用的泛型:List<T>和Dictiona ...