如何在Delphi中从接口类型数据初始化一个TGUID常量数组?

8

我想要像这样初始化一个数组 -

Const MyArray : Array[0..0] Of TGUID = (IInterface);

但是它会导致 -
[DCC Error] Test.pas(10): E2010 Incompatible types: 'TGUID' and 'string'

为了看看会发生什么,我尝试了这个 -

Const MyArray : Array[0..0] Of String = (IInterface);

这将导致以下结果!
[DCC Error] Test.pas(10): E2010 Incompatible types: 'string' and 'TGUID'

多么奇怪!明明IInterface只可能是其中之一,但它似乎执意转化为错误的类型。

7个回答

14

你可以从接口声明中提取GUID并将它们声明为(字符串)常量。然后,您可以在接口声明和数组常量声明中使用这些常量。编译器接受有效的GUID字符串作为TGUID所期望的内容。无效的字符串导致E2204“不正确的GUID语法”编译错误。

const
  MyGuid1 = '{99BDAB12-B1B6-41B0-9BF1-2C1DB3D8EC70}';
  MyGuid2 = '{8C7CD303-8D81-469B-99ED-E1F163E9036F}';

type
  IMyInterface1 = interface
    [MyGuid1]
  end;

  IMyInterface2 = interface
    [MyGuid2]
  end;

const
  MyArray: array[0..1] of TGUID = (MyGuid1, MyGuid2);

我最喜欢这个,虽然比我希望的要手动一些,但看起来它不会为任何后续的程序员留下任何陷阱,这是最重要的。谢谢! - David

3

如果您使用const数组,则必须使用const值进行设置,如下所示:

const GuidArray: array[0..0] of TGuid=
  ('{84DBCC66-72AA-4806-AE28-B55FC5B83FC8}');

啊,这样可以。不过我想直接从接口类型中提取GUID,因为手动同步它们有点危险。 - David

2
你可以编写一个函数来返回GUID数组(我使用此技术来表示常量日期值)。
  • 它不是“真正”的常量,但应该可以在通常使用常量的任何地方使用。
  • 但它也不能使用“可赋值类型常量”选项进行修改。 作弊是不允许的 :)
  • 因此,在初始化部分设置全局变量的方式相比之下,它具有微小的优势。
  • 此外,这比将接口使用的GUID移动到自己的常量中少了一些手动操作。

您可以选择返回动态或固定大小的数组。

选项1

type
  TGUIDArray = array of TGUID;

function GetMyInterfaces: TGUIDArray;
begin
  SetLength(Result, 2);
  Result[0] := IMyInterface1;
  Result[1] := IMyInterface2;
end;

Option 2

type
  TGUIDArray = array[0..1] of TGUID;

function GetMyInterfaces: TGUIDArray;
begin
  Result[0] := IMyInterface1;
  Result[1] := IMyInterface2;
end;

1

我刚在C++Builder中尝试了一下:

const TGUID g = __uuidof(IInterface);
const TGUID MyArray[] = {__uuidof(IInterface)};

我怀疑使用显式关键字 __uuidof 可能会避免你遇到的问题,但它只是用非常相似的东西来替换它。虽然第一行代码可以正常工作,但第二行却会产生以下错误:

[C++ Fehler] Unit1.cpp(9): E2034 Konvertierung von 'const _GUID' nach 'unsigned long' nicht möglich

(中文:[C++错误] Unit1.cpp(9):E2034 无法将'const _GUID'转换为'unsigned long')

很有趣,Delphi 中是否有 __uuidof 等效的方法?只是使用 Const MyGUID: TGUID = IInterface; 对我来说会产生错误。 - David
我不知道。我尝试了一些转换,比如TGUID(IInterface),但都没有起作用。也许现在是一些Delphi编译器工程师应该加入的时候了?;-) - Uli Gerhardt

1

另一个想法:以下代码可以编译:

procedure Blah(const MyArray: array of TGUID);
begin
  //...
end;

Blah([IInterface, IDispatch]);

也许你可以尝试这种方法。


这是一个非常好的方法。它恰好不适合我的情况,但我可以想象经常能够将事物重新组织成这种方法。 - David

0

您可以创建一个 IInterface 数组。


我实际上需要GUID,而不是IInterface的实例。 - David

0

我发现了一种方法,利用传统上在Delphi中常量并不是真正的常量。需要编译器开关才能返回到这种行为(在D2007中)

{$J+}
Const MyArray : Array[0..0] Of TGUID = (());
{$J-}

在初始化部分 -
MyArray[0] := IInterface;

1
我猜在那种情况下,只需使用“var MyArray…”会更容易。 :-) - Uli Gerhardt

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