C/C++ 您当前所在位置:首页 > C/C++ > 静态链接库和动态链接库

静态链接库和动态链接库

陈成 陈成 2020-08-01 19:03:06 C/C++ 131人已围观

简介 开发项目的时候有些代码会经常使用,我们会把它封装成函数避免重复编写,有两种方式,静态链接库和动态链接库。

不管静态链接库还是动态链接库,都是为了解决代码的重用性。

1、静态链接库

创建一个静态链接库项目。

打开VC++,文件-》新建-》Projects,选择Win32 Static Library,起个名字,确定。

新建一个Class后在cpp文件加入你想要加的代码

int Plus(int x, int y)
{
	return x + y;
}

int Sub(int x, int y)
{		
	return x-y;
}

并且在头文件声明一下

int Plus(int x, int y);
int Sub(int x, int y);

完了后直接F7编译一下,然后去项目目录找到xxx.lib文件和xxx.h文件,复制到你要使用这些代码的项目里。

复制到项目里后还不能使用,要使用的话我们有两种方式来使用。

第一种使用方式

先包含头文件

#include "xxx.h"

还要加一行

#pragma comment(lib,"libTool.lib")

加上上面两行代码后就可以使用了。

第二种使用方式

首先还是要先包含头文件

#include "xxx.h"

再在左边项目右键-》setting-》link-》Object/ilbrary modules里面加上你的lib文件确定即可。

静态链接库优缺点

静态链接库优点是比较方便,缺点就是其实它是一种假的模块化,在编译的时候就把代码直接放到exe中了,如果当库更改了,编译的时候又会重新将exe编译一次。

2、动态链接库

文件-》新建-》Projects,选择Win32 Static Library,起个名字,确定。

还是新建一个Class后在cpp文件加入你想要加的代码

int Plus(int x, int y)
{
	return x + y;
}

int Sub(int x, int y)
{		
	return x-y;
}

头文件声明,这里和静态的头声明不一样。

extern "C" _declspec(dllexport) __stdcall int Plus (int x,int y);
extern "C" _declspec(dllexport) __stdcall int Sub (int x,int y);

关键字解释

extern:表示这个是全局函数,可供各个其他函数调用;

"C":表示按照C语言的方式进行编译、链接;

_declspec(dllexport):告诉编译器此函数为导出函数,这个是必须的,要导出的话一定要写这个告诉编译器。

__stdcall:内平栈,如果导出用这种方式,导入也要使用这种方式。

使用DLL有两种方式

第一种:隐式连接

1、首先将xx.dll和xx.lib放到项目里面。在静态链接库里,lib文件放了代码,但这里就不是这样了,这里代码放在dll文件里,而lib文件里放则放的是代码在哪里。

2、将 #pragma comment(lib,"DLL名.lib") 添加到调用文件中

3、加入函数声明

extern "C" __declspec(dllimport) int Plus (int x,int y); 
extern "C" __declspec(dllimport) int Sub (int x,int y);

__declspec(dllimport)告诉编译器此函数为导入函数

第二种:显示连接

1、定义函数指针

typedef int (__stdcall *lpPlus)(int,int);
typedef int (__stdcall *lpSub)(int,int);

2、声明函数指针变量

lpPlus myPlus;
lpSub mySub;

3、加载DLL文件到内存

HINSTANCE hModule = LoadLibrary("testDll.dll");

4、取函数地址

myPlus = (lpPlus)GetProcAddress(hModule,   "Plus");
mySub = (lpSub)GetProcAddress(hModule,   "Sub");

这里要注意,如果函数的调用约定是__stdcall的话,即使是extern "C"导出,在取函数地址的时候,会有一点变化,第二个参数函数名要写成下划线+原函数名+@+数字,类似“_Plus@8“,其中这个8是堆栈平衡的大小。

5、调用函数

int p = myPlus(100,10);
int s = mySub(100,10);

HINSTANCE说明

Handle 是代表系统的内核对象,如文件句柄,线程句柄,进程句柄。

HMODULE 是代表应用程序载入的模块。

HINSTANCE 在win32下与HMODULE是相同的东西 Win16 遗留。

HWND 是代表窗口句柄。

其实这些句柄就是一个无符号整型,Windows之所以这样设计有2个目的,一是可读性更好,二是避免在无意中进行运算。

隐藏dll里面的函数名

生成dll以后别人可以通过工具或其他手段什么的看到里面的函数,这是不允许的,所以我们可以在生成dll的时候 ,将函数名隐藏起来。这时候我们不在要头文件里写上dllexport等关键字,就按平常书写的方式写就可以了,然后再创建一个.def的文本文件,加入以下代码

EXPORTS
Plus   @12
Sub      @15 NONAME

前面是函数名,后面是导出序号,任何一个函数都有一个名和一个导出序号。之前那种导出也是有序号的,是默认生成的。而这个是我们自己写的,这个序号可以自己改,这样可以达到隐藏函数名的目的。

文章评论

发送

站点信息

  • 上线时间:2020年05月30日
  • 网站程序:自建框架
  • 博客模板:今夕何夕
  • 文章统计43篇文章
  • 评论统计0条评论
  • 留言统计0条留言
  • 统计数据:百度统计