【发布时间】:2015-07-28 17:47:17
【问题描述】:
在一个常见的 Delphi 模式中,我将一个值作为 untyped const 传递给一个函数:
procedure DoSomething(const Something; SomethingLength: Integer);
begin
//...
end;
在这个例子中,我恰好传递了 Windows FORMATETC 结构:
procedure Test;
var
omgp: TFormatEtc;
begin
omgp := Default(TFormatEtc);
omgp.cfFormat := RegisterClipboardFormat('CF_PNG');
omgp.ptd := nil;
omgp.dwAspect := DVASPECT_CONTENT or DVASPECT_THUMBNAIL;
omgp.lindex := -1; //all pages
omgp.tymed := TYMED_HGLOBAL;
DoSomething(omgp, SizeOf(omgp));
end;
我需要得到这个数据的地址,所以我可以把它传递给一个底层的Windows函数需要指向数据的指针的东西。
为了做到这一点,我一直使用Pointer(@data):
procedure DoSomething(const Something; SomethingLength: Integer);
begin
SomethingThatNeedsAPointer(Pointer(@Something));
end;
直到这个 API 调用在一种特殊情况下失败(它返回错误的值)。 没有特别的原因,我碰巧仔细查看了正在传递的指针值。当我在调试器中检查every参数值时,我注意到了一些可怕的事情。我注意到:
@Something
Pointer(@Something)
返回不同的值。
-
@Something应该已经是一个指针了 -
Pointer(@Something)应该是多余的演员表
哪种方式正确获取无类型数据的地址?
编辑:人们去吃午饭的东西与问题无关。我已经编辑了这个问题,希望人们能专注于这个问题,而不是例子。
【问题讨论】:
-
在 XE2 中,@Salt 和 Pointer(@Salt) 具有相同的值。如果您遇到问题,您可以作弊并使用
absolute获取地址。声明一个字节的局部变量或类似的东西,并将其绝对为salt。然后获取本地变量的地址。 -
您的代码无法编译。 DoSomething 需要 2 个参数。
-
最后,使用字符串保存二进制数据是在玩火。对于非 ASCII 数据,预计会出现与语言环境相关的失败。它是二进制的。不要假装其他。你不是用 PHP 编码,你有一个选择。
-
人们去吃午饭,吃的东西与问题无关。我已经编辑了这个问题,希望人们能专注于这个问题,而不是这个例子。 几乎没有。 FWIW,我回答了这个问题,并对文本/二进制问题发表了评论。您的编辑让我们的答案现在看起来很奇怪。
-
好的。正如@Sertac 的评论。这是一个有效的评论。 FWIW,我不喜欢传递
salt[1]。如果盐是空的怎么办?Pointer(salt)^更好。将文本视为二进制的问题取模。无论如何,你永远不会避免人们对附带问题发表评论。这就是程序员的想法。
标签: delphi delphi-xe6