189 8069 5689

静态库和动态库编程技术-创新互联

(1)库

创新互联建站专注于企业全网整合营销推广、网站重做改版、海林网站定制设计、自适应品牌网站建设、成都h5网站建设商城网站建设、集团公司官网建设、外贸营销网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为海林等各大城市提供网站开发制作服务。

一、什么是库

    库从本质上来说是一种代码重用的方式,即预先编译可执行代码的二进制格式,

可以被载入内存中,执行,比如C运行库,里面实现了基本的函数,我们无需在写一遍,直接调用接口即可.

库分为静态库和动态库两种,

二、静态库和动态库区别

1.静态函数库


这类库名字一般是xxx.lib,利用静态编译的文件比较大,因为这个函数库的所有数据

都会被整合进目标代码中

优点: 即编译后执行程序不需要外部的函数库支持,因为所有使用的函数都被编译进去了,

缺点: 如果静态函数库里的东西改变了,那你的程序也必须重新编译.

2.动态函数库

库名字一般是 xxx.dll(也可以包含xx.lib用于编译时的链接处理,也可以不包含,

直接动态调用 )


动态函数库不会被编译到目标代码中,你的程序执行到相关代码时才调用库函数.

优点: 因此动态函数库产生的执行文件比较小,因为没有整合到你的程序

动态函数库改变不会影响你的程序。动态函数库升级方便.

缺点: 程序在运行环境中必须提供相应的库,

三、静态库实例

1. 选择Win32项目

静态库和动态库编程技术

2.预编译头,自动生成stdafx.h头文件,作用是获得更快的编译速度

静态库和动态库编程技术

3.添加一个类

静态库和动态库编程技术

4.添加加法接口,和c++一样,不做讲解. 注意函数的实现要放在cpp文件,

虽然没错误, 但是违背了静态库的初衷,

5.实现单独的接口,不依赖类,比如实现一个减法接口

这样声明 extern "c"让编译器这部分但按c形式进行编译

在头文件

extern "C"

{

int sub(int a,int b);

int Doubles(int a);

}

6.然后编译生成

静态库和动态库编程技术

7.导入使用,接口声明在.h文件,所以需要.h找到函数,

使用代码导入lib

#pragmacomment(lib,"lib名.lib")

静态库和动态库编程技术

如果你要方便,可以直接放工程目录

静态库和动态库编程技术

如果你的lib文件在别的地方,你可以说设置附加库目录

静态库和动态库编程技术

如果你不想在代码导入lib 可以在这里导入

静态库和动态库编程技术

8.创建对象调用接口

	CTestLib t;
	//调用类接口
	int a = t.Add(10,10);

	//调用函数
	int subs = sub(30,10);
	int dbInter = Doubles(30);

四、动态库实例

1.创建Win32项目,DLL即可

静态库和动态库编程技术

2.DllMain函数

静态库和动态库编程技术

作用: 动态库dll和静态库区别是: 动态库是可以独立运行的文件,

通俗说他和可执行文件没有多大区别

当其他可执行程序(exe或者其他dll)调用该dll时候,系统会执行一个入口函数.


做一些初始化之类的工作,当然这个入口函数和可执行文件exe有一个大的区别


就是这个入口函数  不是必须的, 也就是说没有这个函数依然能编译dll

参数二表明了系统调用DLL的原因:

DLL_PROCESS_ATTACH  进程加载

DLL_PROCESS_DETACH  进程卸载

DLL_THREAD_ATTACH  线程加载

DLL_THREAD_DETACH  线程卸载

通过这四种情况分析系统何时调用轮到DllMain

3.DLL_PROCESS_ATTACH


一个程序要调用DLL里的函数,首先要把DLL文件映射到进程的地址空间,

要把一个DLL文件映射到进程的地址空间,两种方法:

静态链接和动态链接的LoadLibrary或者LoadLibarayEx

当一个DLL文件被映射到进程的地址控件时,系统调用该DLL的DllMain函数,

传递fdwReason参数为DLL_PROCESS_ATTACH,这种调用只发生在第一次映射

如果同一个进程来为已经映射进来的DLL再次调用,系统只会增加DLL使用次数,

4.DLL_PROCESS_DETACH

DLL被从进程地址空间解除,DLL处理该值时,应处理相关清理工作

什么时候DLL被从进程的地址空间解除映射呢?有两种情况

1_) FreeLibrary解除DLL映射(有几个LoadLibrary,就要有几个FreeLibrary)

2_) 进程结束而解除DLL映射,在进程结束前还没有解除DLL时,进程结束会解除

DLL映射,如果是调用 TerminateProcess终止指定进程和其线程

系统就不会调用DLL_PROCESS_DETACH

5.DLL_THREAD_ATTACH

当进程创建线程时,系统查看当前映射到进程地址空间中的所有DLL文件映射,

DLL_THREAD_ATTACH会触发

新创建的线程负责执行DLL的DllMain函数, 当所有的DLL都处理完后,系统才运行

进程执行其他的线程函数

每次新建线程都会调用, 线程中建立线程也会调用。

6.DLL_THREAD_DETACH

线程调用ExitThread结束线程,(线程函数返回时, 系统也会自动调用ExitThread)

系统查看当前进程空间中所有的DLL映射文件, 并DLL_THREAD_DETACH调用DllMain函数

通知所有DLL执行线程清理工作

五、动态库导入导出

1.打开C++ 预处理器

区分动态库是导入的还是导出的

静态库和动态库编程技术

2.有一个自定义的预定义,这个预定义随便是什么,因为这个

只在你这个工程有效,其他的无效

3.如果有这个定义说明是导出

如果没有这个定义说明是导入

现在这个宏定义是定义的,所以他是导出.

静态库和动态库编程技术

4.类名前面添加即可

静态库和动态库编程技术

5.添加类函数

声明 不需要调用形式,  给类添加即可

静态库和动态库编程技术

实现

静态库和动态库编程技术

C语言形式 全局接口 声明前加上调用形式

静态库和动态库编程技术

6.编译生成

静态库和动态库编程技术

7.导入和使用动态库,所以操作和静态库一样,就是多个个DLL文件

这个文件和exe放一个目录,会静态链接

8.动态库还有一种链接方式,动态加载dll: LoadLibrary

所谓动态载入,就是程序运行时候不必一开始就载入dll。


在程序需要的时候,动态加入进来,

这样我们就不再使用lib来做静态连接, 甚至连,h头文件 都不用了,

直接用GetProcAddress来使用,但是这样的方式来说,都最好只用extern "C"

开头的接口,

9.下载Depends反编译工具 查看dll的内容

上面3个是类风格的

全局形式的Sub函数

静态库和动态库编程技术

10.通过动态链接使用动态函数链接库

动态调用的函数,你得知道函数原型,才能行.

	HMODULE hdl = ::LoadLibrary(L"TestDll.dll");
	
	if(!hdl)
		printf("load error");

	 //获得接口的函数指针. 第二个参数是函数名
	FUNC_SUB fnuc = (FUNC_SUB)::GetProcAddress(hdl,"Sub");
	if(fnuc != NULL)
	{
		printf("110减去20=%d",fnuc(110,20));
	}
	//解除映射
	::FreeLibrary(hdl);

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


分享标题:静态库和动态库编程技术-创新互联
标题链接:http://cdxtjz.cn/article/dosdpe.html

其他资讯