【问题标题】:GlobalFree - Incompatible types: 'NativeUInt' and 'PWideChar'GlobalFree - 不兼容的类型:“NativeUInt”和“PWideChar”
【发布时间】:2019-11-05 08:49:54
【问题描述】:

WinHttpGetIEProxyConfigForCurrentUser 的文档说:

调用者必须释放 lpszProxy、lpszProxyBypass 和 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG 中的 lpszAutoConfigUrl 字符串 如果它们是非 NULL 结构。使用 GlobalFree 释放字符串。

我写了以下代码(Delphi 10.3.2):

var
  VConfig: TWinHttpCurrentUserIEProxyConfig;
begin
  FillChar(VConfig, SizeOf(VConfig), 0);

  if not WinHttpGetIEProxyConfigForCurrentUser(VConfig) then begin
    RaiseLastOSError;
  end;
  ...

  if VConfig.lpszAutoConfigUrl <> nil then begin
    GlobalFree(VConfig.lpszAutoConfigUrl);        // <-- Error
  end;

得到一个错误:

[dcc32 错误] E2010 不兼容的类型:“NativeUInt”和“PWideChar”

问题:

  • 我应该将PWideChar 类型转换为NativeUInt吗?

  • 我可以使用GlobafFreePtr 代替GlobafFree(它接受PWideChar 并且在我的测试中工作正常)?

【问题讨论】:

  • GlobalFreePtr 调用GlobalHandle 从指针获取HGLOBAL,然后调用GlobalUnlock 解锁该句柄,然后调用GlobalFree。我在网上看到的所有例子都直接在指针上调用GlobalFree。我的猜测是,至少现在,GlobalHandle 直接返回其输入值,换句话说,HGLOBAL 与指针相同。我的建议是您直接调用GlobalFree,然后将指针转换为HGLOBALGlobalFree(HGLOBAL(...))
  • @DavidHeffernan 我发现this使用GMEM_FIXED 分配的内存对象的锁计数始终为零。对于这些对象,返回指针的值等于指定句柄的值。 即在某些情况下强制转换指针是不安全的,但应该使用GlobalFreePtr。所以,我认为在所有情况下使用GlobalFreePtr 会更安全。
  • @Anders 的出色回答告诉你你错了,并证明了原因

标签: delphi winapi


【解决方案1】:

当 MSDN 告诉您使用特定功能释放时,那么这样做是您最好的选择。

Windows API 的某些部分是用 C 编写的(有些部分甚至没有定义 STRICT?)以及具有更好类型检查的其他语言在某些地方需要强制转换。

对于 HGLOBAL,您可以使用 GlobalFlags 函数来帮助您。在您的情况下,标志的低字节为零,表示没有锁。如果字符串被分配为可移动的,则文档必须告诉您在访问内存之前要锁定,而事实并非如此。

棺材中的最后一个钉子是调试函数,如果你这样做,你会看到它调用 GlobalAlloc 并将标志设置为 0x40 (GPTR),因此应该传递给 GlobalFree 而无需解锁。如果您的编译器报错,那么您必须转换为适当的类型:

GlobalFree(HGLOBAL(VConfig.lpszAutoConfigUrl)); 

【讨论】:

  • 我希望你不介意,但我用 Delphi 特定内容替换了你答案的最后
  • @DavidHeffernan 这甚至是德尔福演员吗?在我看来像C。可悲的是,我不再记得 Delphi。
  • 是的,这是在 Delphi 中正确的做法。 GlobalFreeWindows.pas 中声明以接受HGBLOAL。现在,HGLOBALTHandle 的别名,NativeUInt 是提问者从那里获得 NativeUInt 的别名。但是,从语义上讲,最好在此处转换为HGLOBAL,以防将来发生任何变化。感谢您在这里插话并填补我对 winapi 知识的空白。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多