采用VS2013创建静态库和动态库

认识静态库和动态库

静态库(静态链接库)、动态库(动态链接库)的作用都是实现代码共享和复用,它们基本概念如下:
静态库:在链接步骤中,链接器将从库文件取得所需的代码,复制到生成的可执行文件中,这种库称为静态库,其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库中的指令都全部被直接包含在最终生成的 EXE 文件中了。在vs中新建生成静态库的工程,编译生成成功后,只产生一个.lib文件(如何区分release和debug,或者说是否区分release和debug有待进一步验证)。
动态库:动态链接库是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。在vs中新建生成动态库的工程,编译成功后,产生一个.lib文件和一个.dll文件(动态库是要区分release和debug的)。

一 静态链接库

1.1创建静态链接库

(1)文件-新建-项目——选择“win32项目”—填写项目“名称”:mylib—点击“确定”——下一步——应用程序类型:选择“静态库”,其余默认选择;
(2)VS平台自动创建了3个文件(2个h文件,1个cpp文件):stdafx.h、targetver.h、stdafx.cpp;
(3)我们需要做的就是手动添加(新建)两个文件mylib.h和mylib.cpp。
头文件mylib.h:

#ifndef MYLIB_H
#define MYLIB_H
void fun(int a); //自定义功能函数
extern int k; //extern 这个关键字的作用:https://www.cnblogs.com/yuxingli/p/7821102.html
class testclass //自定义类
{
	public:
	testclass();
	void print();
};
#endif

源文件mylib.cpp:

#include "stdafx.h"
#include "mylib.h"
#include <iostream>

void fun(int a)
{
	std::cout << a << " mylib generator!\n";
}

int k = 222;

testclass::testclass()
{
	std::cout << "testclass\n";
}

void testclass::print()
{
	std::cout << "this is testcalss function:print()\n";
}

(4)生成解决方案,就会生成一个.lib文件

1.2 使用静态库

需要.h文件,lib文件
(1)设置项目属性–VC++目录–库目录:lib文件所在的目录;比如:mylib\libdebug,mylib\librelease
(2)设置项目属性–链接器–输入–附加依赖项:mylib.lib;或者直接在源代码中加入 #pragma comment(lib, “**.lib”)
(3)设置项目属性–VC++目录–包含目录:h头文件所在目录(也可以在设置项目属性–C/C+±-常规–附加包含目录),在目标源文件中添加h头文件;为了方便管理可以将每一个库的所有文件分类存在一个文件夹下,比如:mylib\include
(4)然后,在目标项目中像平常一样调用普通函数、类、变量,比如:

// testlib.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "iostream"//命名空间std所在的头文件
#include "mylib.h"

#pragma comment(lib, "mylib.lib") //设置这句话后就不需要设置项目链接器属性了

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	fun(4);
	std::cout << k << std::endl;
	testclass tc;
	tc.print();

system("pause"); //调试F5是可以阻塞显示控制台窗口
return 0;
}

二 动态链接库

2.1 创建动态链接库

(1)文件-新建-项目——选择“win32项目”—填写项目“名称”:mydll—点击“确定”——下一步——应用程序类型:选择DLL、附加选项:加选择“导出符号”—点击“完成”;
(2)VS平台自动创建了6个文件(3个h文件,3个cpp文件):myll.h、stdafx.h、targetver.h,dllmain.cpp、mydll.cpp、stdafx.cpp;
(3)我们需要做的就是在头文件myll.h和源文件mydll.cpp中添加自己的变量、函数和类。
头文件实例:

// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 MYDLL_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// MYDLL_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

#include <iostream>  //自主这引用头文件,根据需要添加
#include <string>    //自主这引用头文件,根据需要添加

using namespace std;
// 此类是从 mydll.dll 导出的
class MYDLL_API Cmydll { //Cmydll是用户自定义类名
public:
	Cmydll(void);
// TODO:  在此添加您的方法。
	int setname(string name);

	int setnum(int num);

	int setperunit(int perunit);

	int printinfo();

	int getcost();

private:
	string m_name;
	int m_num;
	int m_perunit;
};

extern MYDLL_API int nmydll; //自定义全局变量

MYDLL_API int fnmydll(void); //自定义函数形式

// 自定义整数加法和乘法  
MYDLL_API int _Add(int a, int b);
MYDLL_API int _Mul(int c, int d);

源文件实例:

// mydll.cpp : 定义 DLL 应用程序的导出函数。
// 函数声明

#include "stdafx.h"
#include "mydll.h"

// 这是导出变量的一个示例
MYDLL_API int nmydll=1;

// 这是导出函数的一个示例。
MYDLL_API int fnmydll(void)
{
	return 22;
}

MYDLL_API int _Add(int a, int b) //注意:关键词MYDLL_API省略似乎也没有太大影响。
{
	return a + b;
}

MYDLL_API int _Mul(int c, int d) 
{
	return c*d;
}

// 这是已导出类的构造函数。

// 有关类定义的信息,请参阅 mydll.h
Cmydll::Cmydll()
{
	return;
}

int Cmydll::setname(string name)
{
	m_name = name;
	return 0;
}

int Cmydll::setnum(int num)
{
	m_num = num;
	return 0;
}

int Cmydll::setperunit(int perunit)
{
	m_perunit = perunit;
	return 0;
}

int Cmydll::printinfo()
{
	cout << "name: " << m_name << endl;
	cout << "num: " << m_num << endl;
	cout << "perunit: " << m_perunit << endl;

	return 0;
}

int Cmydll::getcost()
{
	int cost = m_num*m_perunit;
	return cost;
}

(4)在对应配置条件(release或debug)下,生成解决方案,生成mydll.dll 和mydll.lib;出现一个警告:
“ warning C4251: “Cmydll::m_name”:class“std::basic_string<char,std::char_traits< char > ,std::allocator< char > >” 需要有 dll 接口由 class“Cmydll”的客户端使用 ”,暂时不影响生产库文件。

2.2 使用动态链接库

调用动态库:隐式链接(比较常用的一种方式)
需要.h文件,dll文件,lib文件(release和debug配置环境下生产的文件要区分开,分别应用于目标程序的release和debug配置参数)
(1)将dll放到工程的工作目录(.\Visual Studio 2013\Projects\testmydll\testmydll),推荐存放在调试输出目录中(.\Visual Studio 2013\Projects\testmydll\Debug)
(2)设置项目属性–VC++目录–包含目录:h头文件所在目录(也可以在设置项目属性–C/C+±-常规–附加包含目录),在目标源文件中添加h头文件;为了方便管理可以将每一个库的所有文件分类存在一个文件夹下,比如:mydll\include
(3)设置项目属性–VC++目录–库目录:lib文件所在的目录;比如:mydll\libdebug,mydll\librelease
(4)设置项目属性–链接器–输入–附加依赖项:mydll.lib;或者直接在源代码中加入 #pragma comment(lib, “**.lib”)
(5)在目标项目中,像通常一样调用普通函数、类、变量,比如:

// testmydll.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "mydll.h"

int _tmain(int argc, _TCHAR* argv[])
{
	Cmydll mydll1;
	mydll1.setname("liuwei");
	mydll1.setnum(10);
	mydll1.setperunit(2);
	int getv=mydll1.getcost();
	mydll1.printinfo();  
	nmydll = 2;
	int result;
	result=_Add(5, 1);
	result=_Mul(3, 5);
	system("pause"); //作用:在启动调试的时候(F5)不会出现一闪而过的现象
	return 0;
}

注意:
① 开发32位和64位程序需要的库,需要创建和引用对应配置的库,即32位程序引用win32配置下创建的库,64位程序引用x64配置下创建的库。
② release和debug版本的程序同样需要配置对应版本的库,即release程序引用release版本的库,debug程序引用debug版本的库。

参考博文

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值