《C语言杂记》静态库和动态库(Windows版)

Posted Bruceoxl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《C语言杂记》静态库和动态库(Windows版)相关的知识,希望对你有一定的参考价值。

4 Windows创建和使用静态库

笔者这里使用的是VS2015,当然也可以使用其他工具。

4.1生成静态库

1.首先打开VS,先新建一个项目,选择win32控制台应用程序,当然选择win32项目也可以。

2.接下来选择“下一步”进入应用程序设置,这里选择静态库并去掉预编译头,当然也可以在创建项目后去掉也是可以的。最后点击“完成”即可创建项目。

3.创建头文件(.h)以及源文件(.cpp)
StaticLib.h

#ifndef _STATIC_LIB_H_
#define _STATIC_LIB_H_

#include <iostream>

namespace StaticLib
{
	void print_hello();  //Test function
}

#endif

StaticLib.cpp

#include "StaticLib.h"

void StaticLib::print_hello()
{
	std::cout << "Hello world!" << std::endl;
}

4.生成解决方案,我这里选择的是release

5.编译成功后就可以在工程目录下看到静态库。

4.2使用静态库

1.还是创建个普通的win32控制台程序。

在应用程序设置界面选择“控制台应用程序”,还是不勾选“预编译头”。

2.我们把上面创建lib时的头文件包含到新创建的控制台程序中,同时将lib文件复制到工程目录下。当然也可在编写测试程序时使用库所在的路径。

3.然后在测试源文件中输入以下代码:

#include "StaticLib.h"

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

int main()
{
	StaticLib::print_hello();
	
	system("pause");

    return 0;
}

#pragma comment(lib,“xxx.lib”)表示链接xxx.lib这个库。

4.最后生成并执行工程。

值得注意的是,生成应用程序的环境应与创建库的环境一样。

当然还有一种调用方式。

首先在测试工程目录下新建如下文件夹,将库和头文件分别拷贝到相应的文件夹中。

然后在配置下工程属性:

另外还需要属性页面中选择链接器->输入->附加依赖项中添加新生成的库。

同样也能得到正确结果。

另外,调用的代码更改如下:

#include "StaticLib.h"

int main()
{
	StaticLib::print_hello();
	
	system("pause");

    return 0;
}

当然啦,也可以不配置链接器中的库。还是保留一下语句:

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

以上两种方式本质都是一样的,只是通过不同的方式来配置罢了。




5 Windows创建和使用动态库

5.1生成动态库

1.首先创建一个动态库工程。

和静态库一样,取消去掉预编译头,这里选择DLL。

2.创建头文件(.h)以及源文件(.cpp)

DynamicLib.h

#ifndef _DYNAMIC_LIB_H_
#define _DYNAMIC_LIB_H_

#include <iostream>

#define DLL_EXPORTS

#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
extern "C" {
	namespace DynamicLib
	{
		DLL_API void print_hello();
	}
}

#endif // _DYNAMIC_LIB_H_

DynamicLib.cpp

#include "DynamicLib.h"

DLL_API  void DynamicLib::print_hello()
{
	std::cout << "Hello world!" << std::endl;
}

【注1】__declspec(dllexport)是导出符号,也就是定义需要导出函数的dll中给导出函数的函数声明前面加上导出符号,表示该方法可以导出给其他DLL或者exe使用。

【注2】C++的代码加extern “C”,是为了保证编译时生成的函数名不变,这样动态调用dll时才能。

3.选择release生成解决方案,最后生成的库如下图所示:

好了,动态库就创建好了。

5.2使用动态库

1.还是创建个普通的win32控制台程序。

2.将前面创建的动态库的头文件(.h),dll文件复制到与测试项目中。

3.编写测试

有两种方法调用动态库,一种隐式链接,一种显示链接

先说第一种隐式调用。隐式调用需要.h文件,.dll文件,.lib文件

在源文件加入如下代码:

#include "DynamicLib.h"

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

int main()
{
	DynamicLib::print_hello();

	system("pause");
    return 0;
}

然后编译运行。

接下来在看看显式调用。显式调用需要.dll文件,.lib文件

#include <iostream>
#include <windows.h>

typedef int(*dllfun)(void);//定义指向dll中函数的函数指针

int main()
{
	HINSTANCE hlib = LoadLibrary(L"WindowDynamicLib.dll");

	if (!hlib)
	{
		std::cout << "load dll error\\n";
		return -1;
	}
	dllfun fun = (dllfun)GetProcAddress(hlib, "print_hello");
	if (!fun)
	{
		std::cout << "load fun error\\n";
		return -1;
	}

	fun(); //print_hello()
	
	FreeLibrary(hlib);
	
	system("pause");

    return 0;
}

结果和隐式调用一致。




6静态库和动态库总结

静态库:编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

静态库的代码在编译时链接到应用程序中,因此编译时库文件必须存在并且需要通过“-L”参数传递给编译器,应用程序在开始执行时,库函数代码将随程序一 起调入进程内存段直到进程结束,其执行过程不需要原静态库存在。

动态库:动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。相当于静态库,不同的应用程序可以使用同一份动态库,因此可以节省内存。另外,而且动态库还可被其他语言调用,诸如Python。

总之,静态库和动态库的载入时刻不同,静态库是编译时用到的,动态库是运行时用到的。以Windows为例,如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll。




欢迎访问我的网站

BruceOu的哔哩哔哩
BruceOu的主页
BruceOu的博客
BruceOu的CSDN博客
BruceOu的简书


欢迎订阅我的微信公众号

以上是关于《C语言杂记》静态库和动态库(Windows版)的主要内容,如果未能解决你的问题,请参考以下文章

《C语言杂记》静态库和动态库(Linux版)

《C语言杂记》静态库和动态库(Linux版)

《Python开发 - Python杂记》Python与C/C++混合编程

《Python开发 - Python杂记》Python与C/C++混合编程

C语言Linux下动态库和静态库详解

C语言里面的动态库和静态库