链接器

C 运行时库 /MT /MTD /MD /MDD

寵の児 提交于 2019-12-17 22:20:19
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 转自: http://blog.csdn.net/miyunhong/article/details/5309130 VC编译选项 多线程(/MT) 多线程调试(/MTd) 多线程 DLL (/MD) 多线程调试 DLL (/MDd) C 运行时库 库文件 Single thread(static link) ML libc.lib Debug single thread(static link) MLd libcd.lib MultiThread(static link) MT libcmt.lib Debug multiThread(static link) MTd libcmtd.lib MultiThread(dynamic link) MD msvert.lib Debug multiThread(dynamic link) MDd msvertd.lib 3. 各种 C 运行时库的区别 ( 1 )静态链接的单线程库 静态链接的单线程库只能用于单线程的应用程序, C 运行时库的目标代码最终被编译在应用程序的二进制文件中。通过 /ML 编译选项可以设置 Visual C++ 使用静态链接的单线 程库。 ( 2 )静态链接的多线程库 静态链接的多线程库的目标代码也最终被编译在应用程序的二进制文件中

汇编语言基于X86处理器---基本概念1.1

醉酒当歌 提交于 2019-12-13 23:59:13
对 汇编语言基于X86处理器 书中知识点的整理,可能会有自己的理解,后续也可能会有作业代码。 汇编器和链接器 汇编语言和机器语言的关系 高级语言和汇编语言的关系 什么是可移植语言 汇编语言的应用场景 汇编器和链接器 汇编器 是一种工具程序,用于将汇编语言源程序转换为机器语言。 链接器 的作用是将汇编器生成的单个文件组合为一个可执文件。 调试器 是在程序运行状态下单步执行并检查寄存器和内存状态的工具。现在常用的调试器有OD,X64(x96)DBG(可以调试64位程序),DtDebug(一种可以调试VT的调试器)。 汇编语言和机器语言的关系 机器语言 是一种能被计算机CPU理解并处理的机器语言。所有X86处理器都能理解共同的机器语言。 汇编语言与机器语言是 一对一 的关系,每一条汇编指令都.对应一条机器语言指令。 高级语言与汇编语言的关系 C++,JAVA,Python与汇编语言和机器语言的关系是 一对多 的关 系。即一条高级语言指令对应多条汇编语言。 语言的可移植性 一种语言,如果它的源程序能够在各种各样的计算机系统中进行编译和运行,我们说这种语言是 可移植 的。 汇编语言是一种规格较少的语言,但是由于他是以目标处理器及其机器语言的物理局限性为基础的语言,所以他是一种不可移植的语言。C++是一种移植性差的语言,JAVA和Python是可移植的语言。

链接过程详解

橙三吉。 提交于 2019-12-11 05:39:26
一:链接的基本概念 链接(linking)是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并执行。 链接可以执行于编译时,也可以执行于加载时,甚至执行于运行时。在现代系统中,链接是由叫做链接器(linker)的程序自动执行的。 为什么需要链接器呢?一切都是为了简单、为了方便!试想一下,一个巨大的工程有巨大的源文件,包含N多个模块,如果没有链接的存在,那么当你改动某个模块时,不得不重新编译整个工程,消耗巨大的时间和资源。而在链接器的帮助下,你只需要简单编译修改过的模块,之后重新链接生成可执行文件就OK了。 下面,我们将基于一个运行Linux的x86-64系统,详细讨论关于链接的各个方面。 二:从代码到可执行文件 考虑如下的一个c语言程序: code/link/main.c int sun(int *a, int n); int array[2] = {1, 2}; int main() { int val = sum(array, 2); return val; } code/link/sum.c int sum(int *a, int n) { int i, s = 0; for (i = 0; i < n; i++) s += a[i]; return s; } 从源文件到可执行文件需要哪几个步骤呢? 1:预处理器将C的源程序main

xmake从入门到精通9:交叉编译详解

岁酱吖の 提交于 2019-12-09 07:16:26
xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验。 除了win, linux, macOS平台,以及android, ios等移动端平台的内建构建支持,xmake也支持对各种其他工具链的交叉编译支持,本文我们将会详细介绍下如何使用xmake进行交叉编译。 项目源码 官方文档 交叉编译工具链简介 通常,如果我们需要在当前pc环境编译生成其他设备上才能运行的目标文件时候,就需要通过对应的交叉编译工具链来编译生成它们,比如在win/macos上编译linux的程序,或者在linux上编译其他嵌入式设备的目标文件等。 通常的交叉编译工具链都是基于gcc/clang的,大都具有类似如下的结构: /home/toolchains_sdkdir - bin - arm-linux-armeabi-gcc - arm-linux-armeabi-ld - ... - lib - libxxx.a - include - xxx.h 每个工具链都有对应的include/lib目录,用于放置一些系统库和头文件,例如libc, stdc++等,而bin目录下放置的就是编译工具链一系列工具。例如: arm-linux-armeabi-ar arm-linux-armeabi-as arm-linux

Visual C++ 中的重大更改

一世执手 提交于 2019-12-06 22:35:05
此文章由人工翻译。 将光标移到文章的句子上,以查看原文。 更多信息。 Visual C++ 中的重大更改 Visual Studio 2015 当你升级到 Visual C++ 编译器的新版本后,可能会在之前编译并正常运行的代码中遇到编译和/或运行时错误。新版本中会引起这类问题的更改称为 重大更改 ,通常,修改 C++ 语言标准、函数签名或内存中的对象布局时需要进行这种更改。 若要避免难以检测和诊断的运行时错误,我们建议你永远不静态链接到使用不同编译器版本编译的二进制文件。此外,当你升级 EXE 或 DLL 项目时,请确保升级它所链接的库。如果使用 CRT(C 运行时库)或 STL(标准模板库)类型,请勿在使用不同编译器版本编译的二进制文件(包括 DLL)之间传递这些类型。有关详细信息,请参阅 跨 DLL 边界传递 CRT 对象时可能的错误 。 我们进一步建议,你在编写代码时永远不依赖除 COM 接口或 POD 对象以外的特定对象布局。如果确实要编写此类代码,则必须在升级后确保其正常运行。有关详细信息,请参阅 ABI 边界处的可移植性(现代 C++) 。 本文的其余部分介绍了 Visual Studio 2015 中的 Visual C++ 中具体的重大更改,并且在本文中,术语“新行为”或“现在”均指该版本。术语“旧行为”和“之前”指 Visual Studio 2013

Linux 动态库相关知识整理

会有一股神秘感。 提交于 2019-12-06 06:39:50
动态库和静态库在C/C++开发中很常见,相比静态库直接被编译到可执行程序,动态库运行时加载使得可执行程序的体积更小,更新动态库可以不用重新编译可执行程序等诸多好处。作者是一个Linux后台开发,这些知识经常用到,所以整理了一下这方面的知识。静态库相对简单,本文只关心Linux平台下的动态库。 创建动态库 这里我把一个短小却很有用的哈希函数编译成动态库做为示例,ELFhash用于对字符串做哈希,返回一个无符号整数。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //elfhash.h #include unsigned long ELFhash( const char * key); //elfhash.c #include "elfhash.h" unsigned long ELFhash( const char * key) { unsigned long h = 0, g; while ( *key ) { h = ( h > 24; h &= ~g; } return h; } 接下来使用gcc编译以上代码,并用ld将编译的目标文件链接成动态库 1 2 gcc -fPIC -c -Wall elfhash.c ld -shared elfhash.o -o libelfhash.so 其中 -fPIC 意思是生成位置无关的代码(Position

正确创建本地C++发布构建PDBS

自作多情 提交于 2019-12-05 23:54:06
在调试版本中遇到的一个问题是编译本地的C++应用程序。例如,许多局部变量消失了,因为代码生成器没有将它们放在堆栈上,而是将它们放在寄存器中,就像在调试生成中发生的那样。此外,release积极地构建对函数的内联调用,因此代码生成器将函数体直接放入调用方法中。一旦您习惯了编译器的模式,并了解了一点汇编语言,就不难理解在调试发行版生成代码时会发生什么。 我想在本文中介绍的是在不加应用程序的情况下正确创建本地C++发布PDB所必需的精确开关,这样我就可以回答隐形的问题了。我将向您展示的开关与优化无关,PDB文件的创建不会影响优化。 要设置的第一个开关是在编译器CL.EXE上,它是/Zi。此开关将调试信息放入.OBJ文件中,以便链接器将其放入最终PDB。您将在项目的C/C++属性页中设置这个开关。如下图 接下来的三个开关应用于链接器LINK.EXE。第一个命令/DEBUG告诉链接器您要为该生成创建PDB文件。如下: /DEBUG开关有个小问题。打开它会告诉链接器您正在执行未优化的生成,所以/DEBUG隐式地打开/INCREMENTAL并实质上创建一个调试生成,尽管编译器优化会应用(但不是链接时代码生成优化)。这对您意味着链接器以“快速模式”链接,因此如果您的OBJ中有300个函数,但您只引用(即,使用)其中一个函数,那么链接器会将所有300个函数放入输出二进制文件中。是的

《程序员的自我修养》读书笔记 第二章 编译和链接

戏子无情 提交于 2019-12-05 20:51:15
2.1 被隐藏了的过程 在平常的应用程序开发中一般都不需要关注编译和链接过程,因为在IDE开发环境中一般都将编译和链接合到一起一步完成,直接生成可执行文件;通常将这个过程称为 构建(Buil) 。 对于最经典的C语言版"Hello World"的代码: #include <stdio.h> int main() { printf("Hello World\n"); return 0; } 我们在Linux下使用GCC来编译该代码时,只需使用几行简单的命令就完成对上述代码的编译等一系列过程(假设源码文件名为hello.c),生成可直接运行的的程序: $gcc hello.c $./a.oout Hello World 事实上,上述过程可分解为4个步骤,分别是 预处理(preprocess) 、 编译(compilation) 、 汇编(assembly) 和 链接(linking) ,其中前三个阶段都是文本形式的处理,如下图所示: 下面分别大致介绍下各个步骤的作用。 预编译 预编译过程主要处理那些源代码文件中以“#”开始的预编译指令。比如“#include”、“#define”等,常见的处理规则如下: 将所有的“#define”删除,并且展开所有的宏定义。 处理所有条件预编译指令,比如“#if”、“#ifdef”、“#endif”等。 处理“#include”预编译指令

Linux下显示运行时链接(运行时加载)

六月ゝ 毕业季﹏ 提交于 2019-12-05 14:56:10
目录 介绍 如何加载动态库 dlopen() 第一个参数: 被加载动态库的路径 第二个参数: flag表示函数符号的解析方式 dlopen 返回值 dlsym() 参数: 返回值 符号优先级 dlerror() dlclose() show code 内容学习自《 程序员的自我修养 链接装载与库》 如果只是想知道如何使用如何加载动态库和那4个函数的使用,可以直接从如何加载动态库开始看。 介绍 支持动态链接的系统往往都支持一种更加灵活的模块加载方式,叫做显式运行时链接(Explicit Run-time Linking),有时候也叫做运行时加载。也就是让程序自己在运行时控制加载指定的模块,并且可以在不需要该模块时将其卸载。从前面我们了解到的来看,如果动态链接器可以在运行时将共享模块装载进内存并且可以进行重定位等操作,那么这种运行时加载在理论上也是很容易实现的。而且一般的共享对象不需要进行任何修改就可以进行运行时装载,这种共享对象往往被叫做动态装载库(Dynamic Loading Library),其实本质上它跟一般的共享对象没什么区别,只是程序开发者使用它的角度不同。 这种运行时加载使得程序的模块组织变得很灵活,可以用来实现一些诸如插件、驱动等功能。当程序需要用到某个插件或者驱动的时候,才将相应的模块装载进来,而不需要从一开始就将他们全部装载进来,从而减少了程序启动时间和内存使用

C++链接器

雨燕双飞 提交于 2019-12-04 14:14:14
链接器把多个二进制的目标文件(object file)链接成一个单独的可执行文件 在链接过程中,它必须把符号(变量名、函数名等一些列标识符)用对应的数据的内存地址(变量地址、函数地址等)替代,以完成程序中多个模块的外部引用 对于链接器而言,链接库不过是一个具有许多目标文件的集合 来源: https://www.cnblogs.com/Stephen-Qin/p/11869824.html