龙空技术网

静态库和动态库(Windows版)

嵌入式实验楼 8669

前言:

今天小伙伴们对“vs2017使用静态库”都比较讲究,姐妹们都想要剖析一些“vs2017使用静态库”的相关文章。那么小编同时在网摘上搜集了一些对于“vs2017使用静态库””的相关知识,希望朋友们能喜欢,我们一起来了解一下吧!

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)#endifextern "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;}

结果和隐式调用一致。

显式链接需要.dll, 需要事先知道导出函数的签名,不需要.lib和.h文件

使用显式加载的好处:

通过显式加载动态库的方式可以根据需要加载相应的函数,随时可以卸载,通过判断句柄的方式,不会因为找不到dll导致程序无法启动。如果程序需要访问十多个dll,采用动态加载的方式可以减少程序的启动时间,减小程序占用的内存。6静态库和动态库总结

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

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

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

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

Linux版本如下:

静态库和动态库(Linux版)

标签: #vs2017使用静态库 #linux中静态库和动态库的区别 #linux的动态库和静态库哪个好 #linux 静态库 #静态页面代码及演示页面