RegSetValueEx具有以下P / Invoke签名:

[DllImport("advapi32.dll", SetLastError = true)]
static extern uint RegSetValueEx(
 UIntPtr hKey,
 [MarshalAs(UnmanagedType.LPStr)]
 string lpValueName,
 int Reserved,
 RegistryValueKind dwType,
 IntPtr lpData,
 int cbData);


IntPtr lpData参数可能很麻烦。要传递字符串值,我需要调用Marshall.StringToHGlobal函数之一,然后在完成后释放它。如果将lpData参数的类型更改为[MarshalAs(UnmanagedType.LPStr)]String lpData,我的代码可以更简单。这似乎可行,我可以想象在后台,编组代码正完全按照我要获得IntPtr的方式进行操作。无论这是否合法,我都无法找到任何明确的声明。谁能提供一个?

[是的,我知道有用于与注册表交互的托管代码。在我的特定情况下,我无法使用它,即使我仍然可以对总体答案感兴趣]

最佳答案

是的,这是完全正常且可以接受的技巧。几乎所有类型为BYTE*PVOIDLPARAM的winapi函数参数都适合于自定义的[DllImport]声明。字符串,数组或结构是通常等效的C#参数类型。声明SendMessage()时特别有用。

除了它的结尾,您还可以轻松利用C#语言允许方法重载。换句话说,您可以为lpData参数编写任意数量的具有不同类型的RegSetValueEx()声明。它们都映射到相同的本机函数,因此您无需执行其他任何操作。实际示例is here

您只需要确保编组后传递的值具有预期的字节值即可。请注意,错误往往难以调试,如果呼叫无法解决,您可能仍想手动进行封送处理。这个问题肯定是一个怪癖,您总是想在声明中使用CharSet = CharSet.Unicode,调用ANSI版本(RegSetValueExA)没什么用。现在,您还可以添加ExactSpelling = true

关于c# - 为了方便而更改P/Invoke签名的合法性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43052906/

10-09 03:20