程序的编译与链接

编译与链接过程

编译过程是源程序先被编译器编译为汇编程序,然后再由汇编器将汇编程序汇编成目标文件。
链接过程是链接器将目标文件与需要使用的库文件链接成可执行程序。

静态链接和动态链接

  • 静态链接
    静态链接是说在链接器链接目标文件与库文件时将目标代码与所引用的库文件中的导出函数代码都整合到可执行文件中,静态链接所使用的库文件为静态库(.lib)。
  • 动态链接
    动态链接是说在链接器链接目标文件与库文件时将目标代码与所引用的库文件中的导出函数的名称等信息整合到可执行文件中,动态链接所使用的库文件为导入库(.lib)。再运行时其还会使用到动态库文件(.dll).

静态库和动态库的生成和使用

  • 静态库的生成
    如果想要生成静态库文件需要将配置类型改为:静态库(.lib),并且定义一个.h头文件其中包含导出函数,变量或c++类的符号信息,源文件中是导出函数的定义与实现。这样程序会生成一个静态库文件(.lib)。

  • 动态库的生成
    如果想要生成动态库文件需要将配置类型改为:动态库(.dll),并且定义一个.h头文件其中包含导出函数,变量或c++类的符号信息,源文件中是导出函数的定义与实现。这样程序会生成一个动态库文件(.dll)和一个导入库文件(.lib)。
    需要注意的是这个导入库文件和静态库一样都是lib文件但二者却截然不同,静态库文件中包含了导出函数的代码等信息,而导入库文件只是包含了函数的名称等一些信息供链接器使用。

  • 静态库的使用
    我们只需将生成静态库时使用的头文件包含,然后将静态库文件的路径包含即可。当然静态库文件的路径也可以在配置信息里设置包含。

#include "xxx.h"
#pragma comment(lib, "..\\xxx.lib")
  • 动态库的使用
    我们需要将生成动态库使用的头文件包含,还需要将导入库文件的路径包含。同时如果需要运行它需要将动态库文件dll放在对应程序的目录下。
#include "xxx.h"
#pragma comment(lib, "..\\xxx.lib")

动态/静态库导出函数的命名约定问题

#define EXPORT _declspec(dllexport)
extern "C" EXPORT 函数声明;

EXPORT 宏说明此函数是导出函数,而加上extern "C"是因为c++支持函数重载,所以C++编译器会对源文件中函数的名称做修改附加一些其他符号信息。为了让我们导出的函数名称不被改变,我们需要加上extern “C”来告诉编译器不对函数名称做修改。(这只对函数采用_cdecl调用约定有效)

LIBRATY  动态库名称
EXPORTS
函数名

如果函数时其他调用约定如:_stdcall,_fastcall那么extern "C"就会失效,那么我们就需要借助def文件来处理了。在def中按如上格式加入导出的函数名即可完成函数的导出,而且避免c++编译器修改函数的名称。此外dll除了导出函数还可以导出变量和C++类。

declspec(dllimport)导入的使用

一般在exe可执行文件构建时,如果使用到了某个dll文件中的函数会将此dll生成时包含的.h头文件包含进来。此.h中包含了导出函数的声明,我们可以在函数声明前加上declspec(dllimport)告诉编译器此函数是从其他dll中导入的函数,这样能够产生更为高效的代码。
参考:https://blog.csdn.net/weixin_42018112/article/details/82289971

posted @ 2020-10-06 10:28  怎么可以吃突突  阅读(366)  评论(0编辑  收藏  举报