【问题标题】:Linking FPC .o files into Delphi将 FPC .o 文件链接到 Delphi
【发布时间】:2014-02-26 12:32:52
【问题描述】:

如何将 FPC .o 从库链接到 Delphi 可执行文件。当我尝试链接以下代码时,我得到一堆不满意的前向或外部声明。

library project1;

{$mode objfpc}{$H+}

uses
  Classes
  { you can add units after this };

function Test: Integer;
begin
  Result := -1;
end;

begin
end.


[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'INIT$_$SYSTEM'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'FINALIZE$_$OBJPAS'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'INIT$_$LNFODWRF'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'FINALIZE$_$LNFODWRF'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'INIT$_$FPINTRES'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'FINALIZE$_$WINDIRS'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'SYSUTILS$_$TENCODING_$__$$_create'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'SYSUTILS$_$TENCODING_$__$$_destroy'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'INIT$_$SYSUTILS'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'FINALIZE$_$SYSUTILS'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'INIT$_$TYPINFO'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'FINALIZE$_$TYPINFO'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'INIT$_$CLASSES'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'FINALIZE$_$CLASSES'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'THREADVARLIST_$SYSTEM'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'THREADVARLIST_$CLASSES'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'RESSTR_$RTLCONSTS_$$_START'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'RESSTR_$RTLCONSTS_$$_END'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'RESSTR_$SYSCONST_$$_START'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'RESSTR_$SYSCONST_$$_END'
[dcc64 Error] Project2.dpr(170): E2065 Unsatisfied forward or external declaration: 'FPC_LIBINITIALIZEUNITS' 

【问题讨论】:

  • 出于兴趣,为什么不能在Delphi中编译你的FPC代码? (有很多可能的原因,但如果你能发布为什么我们可以提供帮助。)这样做可以避免整个问题,你可以完全正常地使用你的代码。
  • @DavidM 更多优化,更多 FPU 选择。这就是为什么。 Delphi 32位编译器有SSE3吗?
  • @user3060326 如果你想要真正优化的代码,那么你可以编写 asm.或者你可以使用一个好的 C++ 编译器。 FPC 是否产生高度优化的 FP 代码?我敢打赌英特尔 C++ 编译器会更好。
  • @DavidHeffernan C++ 选项可行但不太可能。
  • 你必须坚持使用 C 风格的代码

标签: delphi freepascal delphi-xe5 fpc


【解决方案1】:

您不太可能完成这项工作,至少按照书面规定。未满足的声明来自 FPC 运行时。您也需要链接它,或者在 Delphi 中重新实现它。这两种选择都不太可行。

当然,如果您删除了对 Classes 单元的引用,并将这个简单的函数放在单独的代码单元而不是库单元中,那么可能没有不满足的声明是合理的。也就是说,您肯定正在探索这一点,因为您想使用实际执行某些操作的 FPC 代码。一旦你这样做了,你就会马上回到原点。

解决这个问题的方法是动态链接到 FPC 代码。将 FPC 代码编译到库中并动态链接到该库。


只是为了好玩,我尝试将 FPC 对象链接到 Delphi 程序。 FPC单元:

unit unit1;

interface

implementation

function Test(i: Integer): Integer; cdecl;
begin
  Test := i*42;
end;

end.

我编译了这个:

fpc unit1.pp

然后我写了下面的Delphi程序来链接它:

{$APPTYPE CONSOLE}

{$L 'unit1.o'}

function Test(i: Integer): Integer; cdecl; 
  external name 'UNIT1_TEST$SMALLINT$$SMALLINT';

begin
  Writeln(Test(666));
end.

输出:

27972

注意函数名是修饰的。为了找到我用的名字objdump

>objdump -d unit1.o unit1.o:文件格式 pe-i386 .text.n_unit1_test$smallint$$smallint 部分的反汇编: 00000000 : 0: 55 推 %ebp 1: 89 e5 移动 %esp,%ebp 3: 83 ec 04 sub $0x4,%esp 6: 0f bf 45 08 movswl 0x8(%ebp),%eax a: 6b c0 2a imul $0x2a,%eax,%eax d: 66 89 45 fc mov %ax,-0x4(%ebp) 11: 66 8b 45 fc mov -0x4(%ebp),%ax 15:c9离开 16:c3 恢复 ...

我使用 x86 版本的编译器完成了这项工作。我希望它在 x64 下也是可行的。

所以你确实可以链接 FPC 对象文件,只要它们足够简单。但是,如果您需要任何 FPC 运行时和标准单元,那么我预计它会变得太难。

【讨论】:

  • 您可以通过使用 Delphi RTL 来解决 RTL 问题。但我不确定这是否会编译。
  • 您不能只替换任何旧的 RTL。它必须是正确的。 FPC 和 Delphi 有不同的 RTL。同样,仅仅因为它们具有相同的名称 (RTL),并不意味着它们可以互换。
  • 当您尝试使用更复杂的类型时会出现更大的问题。甚至将它们用作导出函数的参数/返回值。标准 C 互操作类型(整数类型、浮点类型、指针)以外的类型不能跨互操作边界使用。我知道雷米和我在你之前的问题中告诉过你,你似乎不相信我们。但这是真的。
  • System.pas 怎么样?你的意思是德尔福系统单元?这对任何 FPC 代码都没有用。
  • 可以通过附加 [public,alias:'namethatyoulike'] 为符号设置一个未损坏的名称;在调用约定之后。哦,FPC系统单位是“system.pp”,当然你是对的。
猜你喜欢
  • 1970-01-01
  • 2018-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 2017-12-14
相关资源
最近更新 更多