C++文件说明及使用方法

C++文件说明及使用方法

C++/C程序编译的过程可以粗分为两个阶段:编译和链接;编译又可以分为 预处理、编译、汇编三个阶段
在这里插入图片描述
在编写编译C++的过程中有很多种文件,例如源文件,头文件,静态库文件,动态库文件等。每种类型的文件都有其存在的意义

库文件

库是一些函数和类的集合,其实现了某些特定的功能,是程序的开发免于从头开始。
库有两种:静态链接库和动态链接库!在windows下静态链接库为.lib,动态链接库为.dll;Linux下静态链接库为.a,动态链接库为.so。这里我们只介绍Windows下的库。

1. 特点

无论是静态链接库还是动态链接库,都是库文件,是obj文件的集合,都已经完成了编译过程,它们的作用也是在经历链接后生成可执行文件。在我们的工程中,如果采用静态链接库(静态编译),工程在编译时会导出lib中的声明和实现,并将所有代码都嵌入到宿主程序,生成最终的可执行文件,发布软件时,只需要发布exe文件,不再需要.lib文件;如果采用动态编译库(动态编译),工程在编译过程中只将库中的声明部分导出,嵌入到代码中生成可执行文件,再运行期间动态的去加载卸载.dll。发布软件时,由于可执行文件的实现在dll中,所以dll必须与exe一起发布。静态链接库不能再包含其它库文件,动态链接库可以再包含其它库文件。

2.优缺点

静态链接:占用空间大,程序编译完成后,移植性强;lib不能再包含其它库,扩展性差;库文件升级时需要编译整个工程,灵活性差。

动态链接:占用空间小,库方法更新只需要更换DLL,扩展性和灵活性强

3.静态库生成及使用方法

静态链接库生成方式:以创建test.lib为例

1.新建头文件、源文件

在创建的工程中,打开解决方案资源管理器。在源文件下创建test.cpp,头文件下创建test.h,添加对应的代码。

2.配置属性

在工程的属性表中,修改配置属性

  • 常规->项目默认值->配置类型:将配置类型设置为静态库(.lib)

3.排除工程中的main.cpp(包含main函数的入口文件),生成

静态链接库导入方式:

在项目的属性表中,附加库目录和包含目录,添加依赖项

  • C/C+±>常规->附加包含目录:添加include目录
  • 链接器->常规->附加库目录:添加lib目录
  • 链接器->输入->附加依赖项:添加 tinyxml.lib

4.动态库生成及使用方法

DLL的分类有三种,Non-MFC DLL(非MFC DLL),MFC Regular(MFC规则DLL)和MFC Extension DLL(MFC拓展DLL)。

动态链接库的生成方法:以Non-MFC DLL为例

1.新建一个应用程序类型为DLL的工程

打开VS2015,新建一个VC++空项目,并将应用程序类型设置为DLL,如下:
在这里插入图片描述
工程建立好后,将平台配置修改为Debug|X64

2.添加头文件和源文件

—在解决方案资源管理器中的头文件下添加新项目test.h,代码如下—

#ifndef __TEST_H__
#define __TEST_H__
extern "C" int __declspec(dllexport) add(int num1, int num2);
#endif

头文件中extern "C"是告诉编译器该函数采用C调用方式进行编写

__declspec(dllexport)是声明函数add为dll的导出函数,DLL的导出函数是指可供调用dll的程序调用的函数;如果直接像静态库头文件的调用方式:int add(int num1, int num2)则是DLL的内部函数,DLL内部函数只能用于DLL自身调用,不能供调用DLL的函数调用。

—在解决方案资源管理器中的源文件下添加新项目test.cpp,代码如下—

#include "test.h"

int add(int num1, int num2) {
  return num1 + num2;
}

3.生成动态库

右键解决方案下的TestDLL项目,生成。在工程(解决方案)的x64/Debug文件夹下生成了如下文件,其中包含.lib和.dll
在这里插入图片描述

动态链接库使用方法:

DLL文件的调用方式有两种,一种是显式调用,一种是隐式调用。

—显式调用—

1.在解决方案下新建一个控制台应用项目,命名为TestUseDLL
在这里插入图片描述

2.调用函数

在TestUseDLL.cpp文件中添加如下代码:

#include "stdafx.h"
#include "windows.h"
#include <iostream>
typedef int(*lpAddFun)(int num1, int num2);

int main()
{
  HINSTANCE hDLL;
  hDLL = LoadLibrary(L"TestDLL.dll");
  if (hDLL != NULL) {
    lpAddFun add = (lpAddFun)GetProcAddress(hDLL, "add");
    if (add != NULL) {
      int ret = add(4,5);
      std::cout << ret << std::endl;
    }
    FreeLibrary(hDLL);
  }
  system("Pause");
  return 0;
}


直接通过Windows自带的LoadLibrary函数动态加载DLL模块,并将DLL模块句柄赋给HINSTANCE句柄对象,再通过Windows自带的GetProcAddress函数得到DLL模块中指定函数名的函数指针,并赋值给函数指针add,使用add即可调用动态链接库中的add。程序输出如下:
在这里插入图片描述

—隐式调用—

1.将动态库的头文件,生成的lib文件和dll文件独立打包,如下:
在这里插入图片描述
在新建一个控制台应用项目,在项目的属性表中,附加库目录和包含目录,添加依赖项

  • C/C+±>常规->附加包含目录:添加include目录
  • 链接器->常规->附加库目录:添加lib目录
  • 链接器->输入->附加依赖项:添加 TestDLL.lib

2.设置DLL

工程中DLL的搜索顺序依次为(禁用安全DLL查找模式):

  • 程序运行模块所在目录
  • 当前目录(程序开启的目录)
  • 系统目录:\Windows\System32
  • Windows目录:\Windows
  • 环境变量PATH中的目录

DLL作为我们的资源文件,一定需要被工程找到,我们通常将DLL与工程生成的可执行文件.exe放在同一目录,并一起发布。

3.调用函数

在TestUseDLL.cpp文件中添加如下代码:

#include "stdafx.h"
#include <iostream>
#include "test.h"

int main()
{
  int ret = add(4, 5);
  std::cout << ret << std::endl;
  system("Pause");
  return 0;
}

程序能够正常输出9

5.动态库更新方法

这里的更新有两种:

1.单纯实现方法的更新,头文件未更新:直接替换DLL即可

2.增加新的方法,头文件也更新:替换头文件、.lib库文件以及.dll库文件

6.动态库的跨语言使用
在这里插入图片描述

VS2015中导入文件说明

1.VC++目录->包含目录:添加include目录

2.VC++目录->库目录:添加lib目录

3.C/C+±>常规->附加包含目录:添加include目录

4.链接器->常规->附加库目录:添加lib目录

5.链接器->输入->附加依赖项:添加 TestDLL.lib

上面的1和3都能将头文件的include目录加入到工程,但是区别在于,1中的包含目录会修改系统的Include宏的值,是全局的,而3只针对当前项目,对其它项目没有影响。2与4同理,2会影响全局的库,4只针对当前项目添加库。5是使用的lib文件夹中的依赖项。

参考:

https://www.cnblogs.com/ganxiang/p/13206704.html

https://www.cnblogs.com/tiduswj/p/3716507.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值