如何使用C/C++/在使用图书馆方面,Objective-C与C#相比如何?

如何使用C/C++/在使用图书馆方面,Objective-C与C#相比如何?,c#,c,compiler-construction,clr,C#,C,Compiler Construction,Clr,此问题基于上一个问题: 确认C#编译使用多个过程基本上回答了我最初的问题。此外,答案表明C#使用存储在程序集中的类型和方法签名元数据在编译时检查代码语法 Q:C/C++/Objective-C如何知道在运行时加载哪些在编译时链接的代码?为了将其与我熟悉的技术结合起来,C#/CLR是如何做到这一点的 如果我错了,请纠正我,但对于C#/CLR,我的直觉理解是,在执行时会检查某些路径的程序集,基本上所有代码都是在运行时动态加载和链接的 编辑:更新为C++和ObjuleC与C. 更新:澄清一下,我真正感

此问题基于上一个问题:

确认C#编译使用多个过程基本上回答了我最初的问题。此外,答案表明C#使用存储在程序集中的类型和方法签名元数据在编译时检查代码语法

Q:C/C++/Objective-C如何知道在运行时加载哪些在编译时链接的代码?为了将其与我熟悉的技术结合起来,C#/CLR是如何做到这一点的

如果我错了,请纠正我,但对于C#/CLR,我的直觉理解是,在执行时会检查某些路径的程序集,基本上所有代码都是在运行时动态加载和链接的

<>编辑:更新为C++和ObjuleC与C.</P>
更新:澄清一下,我真正感兴趣的是C/C++/Objective-C编译如何将源代码中的“外部定义”符号与该代码的实际实现相匹配,编译输出是什么,基本上,微处理器是如何执行编译输出的,从而将控制无缝地传递到库代码中(以指令指针的形式)。我已经用CLR虚拟机完成了这一点,但是我很好奇,在实际的微处理器上,C++如何在C++中实现这个概念。

< P> C和C++标准对运行时加载没有什么说明——这完全是OS特定的。对于Windows,可以将代码与导出库(在创建DLL时生成)链接,该库包含函数名及其所在DLL的名称。链接器在包含此信息的代码中创建存根。在运行时,这些存根与Windows LoadLibrary()和相关函数一起被C/C++运行时用来将函数代码加载到内存中并执行它。

库您指的是DLL,对吗


操作系统有特定的模式来查找所需的文件(通常从应用程序本地路径开始,然后转到按环境变量指定的文件夹)。

链接器在C/C++构建中起着重要作用,以解决外部依赖关系。NET语言不使用链接器

有两种外部依赖关系,它们的实现在链接时在另一个作为链接器输入提供的.obj或.lib文件中可用。以及其他可执行模块中可用的。Windows中的DLL

链接器在链接时解析第一个,不会发生复杂的事情,因为链接器知道依赖项的地址。后一步高度依赖于平台。在Windows上,必须为链接器提供导入库。一个非常简单的文件,它只声明DLL的名称和DLL中导出定义的列表。链接器通过在代码中输入一个跳转并向外部依赖关系表中添加一条指示跳转位置的记录来解析依赖关系,以便在运行时对其进行修补。DLL的加载和导入表的设置由Windows加载程序在运行时完成。这是一个鸟瞰的过程,有很多无聊的细节,使这尽快发生

在托管代码中,所有这些都是在运行时完成的,由JIT编译器驱动。它将IL转换为机器代码,由程序执行驱动。每当执行引用另一个类型的代码时,JIT编译器就会启动,加载该类型并转换该类型的被调用方法。加载类型的一个副作用是加载包含该类型的程序集(如果以前未加载该程序集)


值得注意的是,对于构建时可用的外部依赖项,也存在差异。C/C++编译器一次编译一个源文件,依赖项由链接器解析。托管编译器通常将创建程序集的所有源文件作为输入,而不是一次编译一个。事实上,单独编译和链接是受支持的(.netmodule和al.exe),但可用的工具不支持单独编译和链接,因此很少进行单独编译和链接。此外,它不能支持扩展方法和分部类等特性。因此,托管编译器需要更多的系统资源才能完成任务。在现代硬件上随时可用。C/C++的构建过程是在一个资源不可用的时代建立的。

我相信您所问的过程就是所谓的符号解析过程。在一般情况下,它的工作原理是这样的(我试图让它保持操作系统的中立性):

  • 第一步是编译各个源文件以创建目标文件。源代码被转换为机器语言指令,任何未在源文件中定义的符号(即函数或外部变量名)都会导致占位符留在编译后的机器语言代码中,无论它们在何处被引用。未知符号也会添加到目标文件中的列表中-在编译结束时,此列表包含目标文件中所有未解析的符号,并与添加的所有占位符在目标文件中的位置交叉引用。每个对象文件还包含由该对象文件导出的符号列表(即,该对象文件中定义的、它希望使该对象文件外的代码可见的符号)以及这些符号的值

  • 第二步是静态链接。这也发生在编译时。在静态链接过程中,在第一步中创建的所有对象文件和任何静态库文件(只是一种特殊的对象文件)都被合并到一个可执行文件中。静态链接器传递每个对象文件和静态库输出的符号,并构建输出符号(及其值)的完整列表。然后它做一个pa