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

2024-08-30 12:32

本文主要是介绍《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版)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120829

相关文章

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx

C语言中自动与强制转换全解析

《C语言中自动与强制转换全解析》在编写C程序时,类型转换是确保数据正确性和一致性的关键环节,无论是隐式转换还是显式转换,都各有特点和应用场景,本文将详细探讨C语言中的类型转换机制,帮助您更好地理解并在... 目录类型转换的重要性自动类型转换(隐式转换)强制类型转换(显式转换)常见错误与注意事项总结与建议类型

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

Java导出Excel动态表头的示例详解

《Java导出Excel动态表头的示例详解》这篇文章主要为大家详细介绍了Java导出Excel动态表头的相关知识,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录前言一、效果展示二、代码实现1.固定头实体类2.动态头实现3.导出动态头前言本文只记录大致思路以及做法,代码不进

Go语言利用泛型封装常见的Map操作

《Go语言利用泛型封装常见的Map操作》Go语言在1.18版本中引入了泛型,这是Go语言发展的一个重要里程碑,它极大地增强了语言的表达能力和灵活性,本文将通过泛型实现封装常见的Map操作,感... 目录什么是泛型泛型解决了什么问题Go泛型基于泛型的常见Map操作代码合集总结什么是泛型泛型是一种编程范式,允

在 Windows 上安装 DeepSeek 的完整指南(最新推荐)

《在Windows上安装DeepSeek的完整指南(最新推荐)》在Windows上安装DeepSeek的完整指南,包括下载和安装Ollama、下载DeepSeekRXNUMX模型、运行Deep... 目录在www.chinasem.cn Windows 上安装 DeepSeek 的完整指南步骤 1:下载并安装

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤