《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版)的主要内容,如果未能解决你的问题,请参考以下文章
《Python开发 - Python杂记》Python与C/C++混合编程