You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi泛型实例化在BPL与EXE中的差异及编译时类型映射疑问

关于Delphi泛型跨模块实例化与编译时类型索引映射的问题

示例代码

type
  TFoo<T> = class
    class var FCount: Integer;
    constructor Create;
  end;

constructor TFoo<T>.Create;
begin
  inherited Create;
  Inc(FCount);
end;
 
procedure Test;
var
  FI: TFoo<Integer>;
begin
  FI := TFoo<Integer>.Create;
  FI.Free;
end;
 
var
  FI: TFoo<Integer>;
  FS: TFoo<String>; 
begin
  FI := TFoo<Integer>.Create;
  FI.Free;
  FS := TFoo<String>.Create;
  FS.Free;
  Test;
  Writeln(TFoo<Integer>.FCount); // 输出 2
  Writeln(TFoo<String>.FCount);  // 输出 1
end.

问题解答

1. BPL与EXE中的TFoo<Integer>是否为不同类型?

是的,二者属于独立的泛型类型实例。Delphi的泛型类型实例化是基于模块(EXE或BPL)的:每个模块在编译时会独立处理泛型类型的实例化,生成各自的类型元数据和类变量副本。

当你把代码放入BPL后,BPL内部会实例化TFoo<Integer>并维护自己的FCount;而EXE在调用时会自己再实例化一份TFoo<Integer>,这份实例的FCount初始值为0,和BPL中的实例完全隔离,因此你在EXE中读取到的值是0。

2. 编译时类型到索引的映射功能是否仅支持单个BPL?

默认情况下该功能是模块隔离的,但可以通过调整实现逻辑实现跨模块支持:

  • 原方案的核心依赖编译时生成的类型信息与本地映射表,这些数据在不同模块中是独立维护的,每个模块会生成自己的索引映射。
  • 若要跨模块共享,需将映射的核心存储容器(比如全局字典)、类型注册逻辑放在一个共享的公共BPL中,所有需要使用该功能的模块(包括主EXE和其他BPL)都链接这个公共BPL。
  • 同时要确保类型注册逻辑在编译时或初始化阶段统一执行,避免同一类型在不同模块中生成重复索引,保证类型到索引的映射全局唯一。

内容的提问来源于stack exchange,提问作者JoshuaJiang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 16:07:32