Delphi DCU转OBJ

5
有没有一种方法可以将Delphi的.dcu文件转换为.obj文件,以便可以使用像GCC这样的编译器进行链接?我已经有几年没有使用Delphi了,但如果可能的话,我想再次在项目中使用它。

转换是唯一的方法吗?那包装器呢? - someone
你建议使用什么样的包装器? - Hannes de Jager
2
我猜你没有.pas文件(只有.dcu文件),如果有的话,可以看看FreePascal编译器的-A选项(ELF,COFF等),那会简单得多。 - someone
5个回答

14

Delphi可以输出.obj文件,但它们是Intel OMF的32位变体。另一方面,GCC使用ELF(Linux、大多数Unix系统)、COFF(在Windows上)或Mach-O(Mac)。

但这还不足够。没有使用运行时库很难编写大量代码,而运行时库的实现将依赖于编译器和链接器体系结构的低级细节,例如正确的初始化顺序。

此外,与对象文件格式相比,兼容性还有更多的要素; 特别是在Linux上的代码需要是位置无关的,这意味着它不能使用绝对值来引用全局符号,而必须从寄存器或相对于指令指针索引其所有全局数据,以便该代码可以在内存中重定位而不需要重写引用。

DCU文件是Delphi符号表和为每个过程生成的代码的序列化,因此高度依赖于编译器的实现细节,而这些细节会随着版本的更改而发生变化。

所有这些意味着,除非您限制自己使用最少量的非托管数据类型(没有字符串、没有接口)和过程代码(没有类、没有初始化部分、没有需要初始化的数据等),否则您很难将Delphi (dcc32)代码链接到GNU环境中。


你认为FreePascal会让这更有可能吗?它现在与Delphi的兼容性如何? - Hannes de Jager
我认为当FreePascal没有使用自己的东西时,它会与GNU进行交互,所以情况可能会类似。但是我不是FreePascal的专家。 - Barry Kelly
正确的,请参见下面有关FPC的单独响应。 - Marco van de Voort

4
是的。请查看“项目选项”对话框:


(高清版)


该对话框可以让您更改项目相关设置。

问题是它们是否可以被像gcc这样的工具链使用,我认为那些obj文件不兼容。 - Ritsaert Hornstra
希望专家们(Wheeler、Kennedy等)很快就会来决定! - Andreas Rejbrand
@Andreas:不要低估自己。你在这里做得非常好,我认为你可能和我、Rob处于同一水平线上。我们只是比你早来到这里而已。 - Mason Wheeler
1
到目前为止,谢谢 :-) Delphi的obj文件不是OMF格式,win32二进制文件我认为是COFF,而Linux则是ELF。我想这些格式之间应该会有转换器。 - Hannes de Jager
据我所知,C++Builder 以前有一个打包的转换器? - Marco van de Voort

4

为了更好地理解,您需要知道Delphi的.dcu文件可以转换为两个不同的FPC文件,.ppu文件包含所述的符号表信息,其中包括内联函数和通用定义等不可链接的代码,而.o文件在Windows上与mingw兼容(COFF)。Cygwin在链接级别上也兼容mingw(但运行时不同且令人害怕)。无论如何,mingw32/64是我们在Windows上参考的gcc。

PPU与Delphi的DCU有类似的版本问题,可能是出于相同的原因。ppu格式在每个主要版本发布时几乎都不同。(例如2.0、2.2、2.4),并且通常每年在trunk中更改2-3次

因此,尽管FPC在Windows上使用自己的汇编器和链接器,但它生成的.o文件仍与mingw32兼容。总体而言,FPC的输出非常与gcc兼容,通常可以直接链接gcc静态库,允许将mysql和postgres链接库与适当许可证(如GPL)的应用程序链接起来。 在64位上它们也应该兼容,但这可能比win32测试得少。

文本模式IDE甚至以库形式链接整个GDB调试器。 GDB是Windows上gcc兼容性的主要原因之一。

虽然Barry关于运行时的一般观点也适用于FPC,但解决这个问题可能会稍微容易一些。它可能只需要从启动代码中调用某些函数来初始化FPC rtl,并对finalize进行类似的操作。使用-al编译最小的FPC程序并查看生成的汇编程序(在.s文件中,特别是initializeunits和finalizeunits)此外,RTL更灵活,可能更容易缩小到最小。

当然,一旦您还需要跨gcc<->fpc边界使异常工作,您就没有机会了。 FPC不使用SEH或任何与ATM兼容的方案。(与Delphi相反,Delphi使用SEH,在理论上应该在这方面给您一个优势,Barry?)另一方面,gcc可能使用自己的libunwind而不是SEH。

请注意,x86上FPC的默认调用约定与Delphi兼容的寄存器,因此您可能需要插入正确的cdecl(应该与gcc兼容)修饰符,甚至可以使用{$calling cdecl}为整个单位设置。

在*nix上,这是标准的(例如apache模块),但我不知道有多少人在win32上这样做。

关于兼容性;FPC可以编译像Indy、Teechart、Zeos、ICS、Synapse、VST等包,几乎不需要进行修改。发布版本的方言级别是D7及以上的混合,重点是D7。方言级别正在缓慢地向D2006级别移动(具有for in、class abstract等)


2

由于DCU格式是专有的,并且往往会在Delphi的不同版本之间发生变化,因此可能没有可靠的方法将DCU转换为OBJ。最好的方法是按照Andreas的答案,在第一次构建时就使用OBJ格式。


2
据我所知,Delphi仅支持OMF目标文件格式。您可以尝试使用一个目标文件格式转换器,例如Agner Fog's

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接