如何在常量记录的位置传递一个nil?

7

我正在尝试调用WIC(Windows Imaging Component)工厂方法CreateEncoder

HRESULT CreateEncoder(
  [in]            REFGUID guidContainerFormat,
  [in, optional]  const GUID *pguidVendor,
  [out, retval]   IWICBitmapEncoder **ppIEncoder
);

一般的想法是:
var
   encoder: IWICBitmapEncoder;

CreateEncoder(
      GUID_ContainerFormatIco,  //The GUID for the desired container format
      nil, //No preferred codec vendor
      {out}encoder);

对于第二个参数,我希望传递nil来表示我没有编码器偏好。

但是Delphi对WinCodec.pas的翻译如下:

function CreateEncoder(const guidContainerFormat: TGuid; const pguidVendor: TGUID;
      out ppIEncoder: IWICBitmapEncoder): HRESULT; stdcall;          

您会注意到第二个参数,即可选的TGUID,声明为const

那么我该如何将其设置为nil?

在需要const记录的位置传递nil应该怎么做?

我尝试了天真的解决方案:

const
   NULL_GUID: TGUID = ();

factory.CreateEncoder(GUID_ContainerFormatIco, NULL_GUID, {out}encoder);

当发生这种情况时,它并没有真正遵循正确的规则。它传递了一个非空地址,该地址指向API不知道的GUID。

我尝试了天真的解决方案:

factory.CreateEncoder(GUID_ContainerFormatIco, TGUID(nil), {out}encoder);

但这是一个无效的类型转换


3
TGUID(nil^) 也可能起作用。 - David Heffernan
3
@DavidHeffernan: +1 那通常是人们开始对你投以奇怪的眼光的时候。我也经历过这种情况。 - JensG
1个回答

10

你可以像这样使用:

const
  NULL_PGUID: PGUID = nil;
begin
  factory.CreateEncoder(GUID_ContainerFormatIco, NULL_PGUID^, {out}encoder);
end;

或者按照Sertac的建议,简短而甜美的版本:

factory.CreateEncoder(GUID_ContainerFormatIco, PGUID(nil)^, {out}encoder);

我做了一个测试,David的建议是:

factory.CreateEncoder(GUID_ContainerFormatIco, TGUID(nil^), {out}encoder);    

同样有效。


5
将"or PGuid(nil)^"翻译为中文后是:或者将变量保存到PGuid(nil)^。 - Sertac Akyuz
这些比我之前折腾的 TGUID(PGUID(nil)^) 好多了! - Ian Boyd
Ian,你的TGUID(PGUID(nil)^)是一个不错的尝试!你可以省略那个TGUID类型转换,因为PGUID()^已经解引用了一个TGUID值,所以那个类型转换在那里是无用的。PGUID(nil)^可以被理解为你正在解引用一个指向nil指针常量的TGUID指针。TGUID(nil^)则表示你正在解引用nil指针常量,并将该值强制转换为TGUID类型。 - TLama

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