Delphi静态类方法与常规例程指针间兼容性如何实现?

2026-04-10 20:593阅读0评论SEO资讯
  • 内容介绍
  • 相关推荐

本文共计387个文字,预计阅读时间需要2分钟。

Delphi静态类方法与常规例程指针间兼容性如何实现?

在我观察,静态方法和常规示例指针从实际角度是兼容的,但编译器并不知道这一点。例如:type TFunc=function(i: Integer): string; TMyClass=class public class function StaticMethod(i: Integer): string; static; end; cla

在我看来,静态类方法和常规例程指针从实际角度兼容,但编译器不知道这一点.例:

Delphi静态类方法与常规例程指针间兼容性如何实现?

type TFunc = function(i: Integer): string; TMyClass = class public class function StaticMethod(i: Integer): string; static; end; class function TMyClass.StaticMethod(i: Integer): string; begin Result := '>' + IntToStr(i) + '<'; end; function GlobalFunc(i: Integer): string; begin Result := '{' + IntToStr(i) + '}'; end; procedure CallIt(func: TFunc); begin Writeln(func(42)); end; begin CallIt(TMyClass.StaticMethod); // 1a: doesn't compile CallIt(GlobalFunc); // 1b: compiles CallIt(@TMyClass.StaticMethod); // 2a: compiles iff $TYPEDADDRESS OFF CallIt(@GlobalFunc); // 2b: compiles iff $TYPEDADDRESS OFF CallIt(Addr(TMyClass.StaticMethod)); // 3a: compiles CallIt(Addr(GlobalFunc)); // 3b: compiles Readln; end.

如注释中所述,3a和3b都是编译的(其中编译包括在这个简单示例中的运行时工作).当且仅当$TYPEDADDRESS为OFF时,2a和2b都编译.但是1a / 1b是不同的:1b总是编译而1a从不编译.这是设计上的区别吗?使用3a保存还是我忽略了任何陷阱?

静态类函数和具有相同参数和结果类型的普通函数之间的二进制级别没有区别 – 它们是二进制兼容的,因此您的示例是可以的.当然它们是编译器的不同类型,因此您需要Addr()或@来编译您的示例.

Addr()等同于@运算符,除了它不受$T编译器指令的影响.如果你切换类型检查你的例子将无法编译:

{$T+} begin CallIt(@TMyClass.StaticMethod); Readln; end.

[Pascal Error] Project10.dpr(28):E2010不兼容的类型:’TFunc’和’Pointer’

本文共计387个文字,预计阅读时间需要2分钟。

Delphi静态类方法与常规例程指针间兼容性如何实现?

在我观察,静态方法和常规示例指针从实际角度是兼容的,但编译器并不知道这一点。例如:type TFunc=function(i: Integer): string; TMyClass=class public class function StaticMethod(i: Integer): string; static; end; cla

在我看来,静态类方法和常规例程指针从实际角度兼容,但编译器不知道这一点.例:

Delphi静态类方法与常规例程指针间兼容性如何实现?

type TFunc = function(i: Integer): string; TMyClass = class public class function StaticMethod(i: Integer): string; static; end; class function TMyClass.StaticMethod(i: Integer): string; begin Result := '>' + IntToStr(i) + '<'; end; function GlobalFunc(i: Integer): string; begin Result := '{' + IntToStr(i) + '}'; end; procedure CallIt(func: TFunc); begin Writeln(func(42)); end; begin CallIt(TMyClass.StaticMethod); // 1a: doesn't compile CallIt(GlobalFunc); // 1b: compiles CallIt(@TMyClass.StaticMethod); // 2a: compiles iff $TYPEDADDRESS OFF CallIt(@GlobalFunc); // 2b: compiles iff $TYPEDADDRESS OFF CallIt(Addr(TMyClass.StaticMethod)); // 3a: compiles CallIt(Addr(GlobalFunc)); // 3b: compiles Readln; end.

如注释中所述,3a和3b都是编译的(其中编译包括在这个简单示例中的运行时工作).当且仅当$TYPEDADDRESS为OFF时,2a和2b都编译.但是1a / 1b是不同的:1b总是编译而1a从不编译.这是设计上的区别吗?使用3a保存还是我忽略了任何陷阱?

静态类函数和具有相同参数和结果类型的普通函数之间的二进制级别没有区别 – 它们是二进制兼容的,因此您的示例是可以的.当然它们是编译器的不同类型,因此您需要Addr()或@来编译您的示例.

Addr()等同于@运算符,除了它不受$T编译器指令的影响.如果你切换类型检查你的例子将无法编译:

{$T+} begin CallIt(@TMyClass.StaticMethod); Readln; end.

[Pascal Error] Project10.dpr(28):E2010不兼容的类型:’TFunc’和’Pointer’