【发布时间】:2019-09-24 17:00:14
【问题描述】:
我有以下函数的原型:https://docs.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-GetUrlCacheGroupAttributeA
看起来像这样:
[DllImport("wininet", SetLastError = true, CharSet = CharSet.Auto, EntryPoint = "GetUrlCacheGroupAttributeA", CallingConvention = CallingConvention.StdCall)]
private static extern bool GetUrlCacheGroupAttribute(
long gid,
uint dwFlags,
uint dwAttributes,
IntPtr lpGroupInfo,
ref uint lpcbGroupInfo,
IntPtr lpReserved);
lpdwGroupInfo 可能比out 更有意义,而不是ref,否则,我认为这是正确的。
我不明白的是,我应该如何传递一个指向 INTERNET_CACHE_GROUP_INFO 结构 lpGroupInfo 的指针(我也已经定义/原型化了这个函数)。我知道其他所有内容是如何传入的,只是这个指针让我感到困惑。
函数声明指针如下:
lpGroupInfo - 指向接收请求信息的 INTERNET_CACHE_GROUP_INFO 结构的指针。
lpcbGroupInfo - 指向包含 lpGroupInfo 缓冲区大小的变量的指针。当函数返回时,该变量包含复制到缓冲区的字节数,或缓冲区所需的大小,以字节为单位。
我需要通过Marshal.AllocHGlobal 或其他方式分配内存吗?这似乎表明我只会在传入结构后才获得结构的大小,但是如果没有首先定义它,我怎么能传入呢?我完全不清楚如何创建初始指针,以及我应该如何 Marshal.PtrToStructure 它。
【问题讨论】:
-
使用 lpGroupInfo 和 lpcbGroupInfo 调用函数一次为零和 0。这应该会给您返回 lpcbGroupInfo 中所需缓冲区的大小(应该保持参考)。然后按原样使用 AllocHGlobal 传递 lpcbGroupInfo 进行分配,再次调用该函数(并且不要忘记稍后调用 FreeHGlobal)。 PS你应该叫W版本,而不是A版本。
-
@SimonMourier 请原谅我的怀疑,我根本不知道 C 设计模式。您确定预期的方法是调用该函数两次吗?这是一种常见的模式吗?
-
是的,这是一种非常常见的 Windows C API 模式。
-
谢谢西蒙。如果您想为它添加一个,我会将您的答案标记为正确。
标签: c# pointers memory parameters pinvoke