![]() |
1
22
不。在一般情况下,对象文件格式可能相同,例如elf,但对象文件的内容因系统而异。 对象文件包含以下内容:
对象代码通常不仅特定于处理器,而且还特定于操作系统,例如,如果它包含系统调用。 编辑:
当然。如果使用交叉编译器。此编译器专门针对平台并生成与目标平台兼容的对象文件(和程序)。因此,您可以使用x86 Linux系统,例如,使用适当的交叉编译器为基于PowerPC或ARM的系统生成程序。我做到了 here . |
![]() |
2
17
|
![]() |
3
5
实际上,没有。有几件事必须是相同的: -操作系统接口(相同的系统调用) -数据的内存布局(endianness、结构填充等) -呼叫约定 -对象文件格式(例如,ELF在Linux上相当标准) 有关详细信息,请查阅ABI。 |
![]() |
4
4
它不需要再说一遍:C/C++对象文件是不可移植的。 另一方面,ANSIC是目前最可移植的语言之一。您可能无法获取对象文件,但如果您坚持使用ANSIC标准,则重新编译源文件可能会起作用。这也同样适用于C++。 我不知道通用的GNU C++是怎样的,但是如果你可以在一台计算机上用GCC编译,那么你就可以去安装GCC的任何其他机器。几乎每台你能想到的机器都有一个C编译器。 那是 便携性。 |
![]() |
5
4
不,它们不是平台独立的。例如,生成ELF二进制文件的GNUC编译器(gcc)。Windows编译器(Borland、Microsoft、OpenWatcom)可以生成Windows二进制PE(可移植可执行文件)格式。Novell二进制文件是NLM(Netware可加载模块)格式。 以上这些例子说明了不同的输出是编译器依赖的,在Windows平台上的链接器不可能知道任何关于ELF格式或NLM格式的信息,因此不可能组合不同的格式来生成一个可以在任何平台上运行的可执行文件。 以苹果的Mac OSX(在英特尔芯片投入使用之前)为例,它们是在PowerPC平台上运行的,即使它有GNU C编译器,二进制文件也是专门针对PowerPC平台的,如果您要将该二进制文件复制到Linux平台上,它也不会因为平台MIC指令的不同而运行。RoProcessor,即PowerPC。 同样,同样的原则也适用于OS/390大型机系统,一个为该平台生成二进制文件的GNU C编译器不会在英特尔苹果Mac OSX之前的版本上运行。
编辑:
为了进一步澄清ELF格式的外观,可以通过运行
main.o: file format elf32-i386 Contents of section .text: 0000 8d4c2404 83e4f0ff 71fc5589 e55183ec .L$.....q.U..Q.. 0010 14894df4 a1000000 00a30000 0000a100 ..M............. 0020 000000a3 00000000 8b45f483 38010f8e .........E..8... 0030 9c000000 8b55f48b 420483c0 048b0083 .....U..B....... 0040 ec086800 00000050 e8fcffff ff83c410 ..h....P........ 0050 a3000000 00a10000 000085c0 7520a100 ............u .. 0060 00000050 6a1f6a01 68040000 00e8fcff ...Pj.j.h....... 0070 ffff83c4 10c745f8 01000000 eb5a8b45 ......E......Z.E 0080 f4833802 7e218b55 f48b4204 83c0088b ..8.~!.U..B..... 0090 0083ec08 68240000 0050e8fc ffffff83 ....h$...P...... 00a0 c410a300 000000a1 00000000 85c07520 ..............u 00b0 a1000000 00506a20 6a016828 000000e8 .....Pj j.h(.... 00c0 fcffffff 83c410c7 45f80100 0000eb08 ........E....... 00d0 e8fcffff ff8945f8 8b45f88b 4dfcc98d ......E..E..M... 00e0 61fcc3 a.. Contents of section .rodata: 0000 72000000 4552524f 52202d20 63616e6e r...ERROR - cann 0010 6f74206f 70656e20 696e7075 74206669 ot open input fi 0020 6c650a00 77000000 4552524f 52202d20 le..w...ERROR - 0030 63616e6e 6f74206f 70656e20 6f757470 cannot open outp 0040 75742066 696c650a 00 ut file.. Contents of section .comment: 0000 00474343 3a202847 4e552920 342e322e .GCC: (GNU) 4.2. 0010 3400 4. 现在将其与简单dll的PE格式进行比较 C:\Program Files\Microsoft Visual Studio 9.0\VC\bin>dumpbin /summary "C:\Documents and Settings\Tom\My Documents\Visual Studio 2008\Projects\SimpleLib\Release\SimpleLib.dll" Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file C:\Documents and Settings\Tom\My Documents\Visual Studio 2008\Projects\SimpleLib\Release\SimpleLib.dll File Type: DLL Summary 1000 .data 1000 .rdata 1000 .reloc 1000 .rsrc 1000 .text
注意,在elf下,各部分的不同之处在于
希望这有帮助, 最好的问候, 汤姆。 |
![]() |
6
3
它们依赖于平台。例如,“文件”命令打印出以下内容:
|
![]() |
7
2
C++有另外的细节,即将其放入对象文件的名称通常是“MangLED”,以对重载的名称处理类型安全性。用于命名的方法不是C++标准的一部分(事实上,名称Mangle是一个实现细节,如果供应商可以想出一种不同的方法来实现重载,则根本不需要实现细节)。因此,即使对于同一个平台目标,也不能指望能够将对象文件从一个编译器供应商链接到另一个。 有时编译器供应商可能会将名称管理方案从一个编译器版本更改为另一个。例如,我相信有MSVC版本,您不能将C++对象文件从旧版本可靠地链接到较新版本。 一些平台的名称在平台的ABI标准中指定了名称(例如ARM,该名称使用了最初在ItnIn上针对SVR4开发的通用C++ ABI中指定的名称),但其他一些则没有(Windows)。即使对于ARM,我也不知道ABI标准如何使由不同编译器创建的C++对象文件链接起来。 |
![]() |
8
2
我只是想说,只要他们使用相同的 处理器体系结构 对象格式,以及调用约定(通常现在,处理器制造商创建了一个),对象文件有很多机会可以互换工作。 但是,即使在C语言中,编译器也会对某些库函数(如堆栈保护(我知道的))进行一些假设,这两个平台上的函数不必相同。在生成此类代码的情况下,对象将不直接兼容。 系统调用并不真正相关,只要系统像通常那样共享它们,它们是通过标准库中的C包装器调用的。 最后,这只适用于C和非常类似的操作系统,如Linux和BSD,但也可能发生。 |
![]() |
9
1
可以使用gcc编译并以elf文件格式创建对象文件,然后将对象文件转换为在Visual Studio中工作。我已经做了很多次了。 要做到这一点,您需要知道三件事: 函数调用约定、对象文件格式和函数名管理。
函数调用约定:
对于32位模式,函数调用约定很简单:对于Windows和Unix,它们是相同的。对于64位模式,Windows和Unix使用不同的调用约定。因此,在64位模式下,您必须使调用约定正确。您可以在编译时执行此操作,也可以从对象文件本身执行此操作。编译时这样做容易得多。要让GCC使用Windows调用约定,请使用
异议文件格式:
要转换对象文件格式,需要一个工具。我用Agner Fog的objconv工具来做这个。它可以从几个不同的对象文件格式转换。例如,将ELF64转换为COFF64(PE32+)do
函数名管理:
在C++编译器中,由于函数重载,函数名称就变模糊了。每个编译器的详细信息可以在Agner Fog的手册中找到。
calling convetions
. gcc和Visual Studio的mangle函数名称不同。要解决此问题,请使用
如果所有这三个都正确,并且没有进行任何特定于操作系统的调用,则可能无法在编译器之间成功地使用对象文件。当然还有其他问题。有关更多详细信息,请参阅objconv中的手册。但到目前为止,这种方法对我很有效。 |
![]() |
MaPo · Linux,设置锁定ICMP_过滤器选项 4 月前 |
![]() |
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 4 月前 |
![]() |
Bobby · 复合字面值总是左值吗? 4 月前 |
![]() |
9-Pin · C: 嵌套结构的堆栈内存分配 4 月前 |