GlobalFree - 不兼容的类型:'NativeUInt' 和 'PWideChar'。

6

WinHttpGetIEProxyConfigForCurrentUser的文档指出:

如果WINHTTP_CURRENT_USER_IE_PROXY_CONFIG结构体中的lpszProxy,lpszProxyBypass和lpszAutoConfigUrl字符串非空,则调用者必须释放它们。使用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 Error] E2010 不兼容的类型:'NativeUInt' 和 'PWideChar'

问题:

  • 我应该将 PWideChar 强制转换为 NativeUInt 吗?

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


2
GlobalFreePtr calls GlobalHandle to get an HGLOBAL from a pointer, then GlobalUnlock to unlock that handle, then GlobalFree. All the examples I see online call GlobalFree directly on the pointer. My guess is that, these days at least, GlobalHandle returns its input value directly, in other words the HGLOBAL is the same thing as the pointer. My suggestion is that you call GlobalFree directly, and hence cast the pointer to HGLOBAL. GlobalFree(HGLOBAL(...)) - David Heffernan
@DavidHeffernan 我找到了这个使用GMEM_FIXED分配的内存对象始终具有零锁定计数。对于这些对象,返回指针的值等于指定句柄的值。 也就是说,在某些情况下强制转换指针是不安全的,应该使用GlobalFreePtr。因此,我认为在所有情况下使用GlobalFreePtr会更安全。 - zed
@Anders的优秀回答告诉你错了,并解释了为什么。 - David Heffernan
1个回答

8

当MSDN告诉你使用特定函数释放内存时,那么这就是最好的选择。

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

对于 HGLOBALs,你可以使用 GlobalFlags 函数来帮助你。在你的情况下,标志字节的低位为零,表示没有锁定。如果字符串被分配为可移动的,则文档将要求您在访问内存之前进行锁定,但实际上并没有这样做。

最后,调试该函数。如果这样做,您将看到它使用设置为 0x40(GPTR)的标志调用 GlobalAlloc,因此应传递给 GlobalFree 而不需解锁。如果您的编译器提示错误,则必须进行适当类型的强制转换:

GlobalFree(HGLOBAL(VConfig.lpszAutoConfigUrl)); 

希望你不介意,我用 Delphi 特定的内容替换了你回答的最后部分。 - David Heffernan
@DavidHeffernan 这是 Delphi 的转换吗?看起来像是 C 语言。不幸的是,我已经记不清 Delphi 了。 - Anders
4
是的,在Delphi中这样做是正确的。GlobalFreeWindows.pas中声明,接受一个HGLOBAL参数。现在,HGLOBALTHandle的别名,而THandle则是NativeUInt的别名,这也是提问者得到NativeUInt的来源。然而,从语义上讲,在这里强制转换为HGLOBAL是最好的,以防将来发生任何变化。感谢您在此处提供帮助,并填补我对winapi的知识空白。 - David Heffernan

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