理解VB.NET中的VBByRefStr P / Invoke声明

时间:2017-04-13 07:06:45

标签: .net vb.net pinvoke marshalling

当尝试在C#中使用VB.NET程序集中的P / Invoke声明时,我注意到string个参数变为ref string个参数。

仔细检查可以发现,例如

Public Declare Unicode Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueW" ( _
    ByVal hKey As IntPtr, ByVal lpValueName As String) As UInteger

编译为

[DllImport(...)]public static extern uint RegDeleteValue(
    IntPtr hKey, [MarshalAs(UnmanagedType.VBByRefStr)] ref string lpValueName);

On MSDN我读到:" VBByRefStr:一个值,它使Visual Basic .NET能够更改非托管代码中的字符串,并将结果反映在托管代码中。仅对平台调用支持此值。这是Visual Basic for ByVal字符串中的默认值。"

我仍然没有得到它。为什么在C#中只有string lpValueName(请参阅pinvoke.net - 编辑:代表RegDeleteKey,因为Damien_The_Unbeliever指出,签名与RegDeleteValue相同但在VB.NET中奇怪VBByRefStr?我应该在VB.NET中使用<MarshalAs(UnmanagedType.LPWStr)>声明以避免在C#中使用ref吗?或者这会产生任何不利影响吗?

1 个答案:

答案 0 :(得分:3)

这是为了向后兼容VB6 Declare语句。

当使用ByVal x As String时,表示您想要将VB UTF-16“String”类型转换为ASCII表示形式,将指向该ASCII缓冲区的指针传递给该参数,并在调用成功后转换为该缓冲区的内容返回原始的UTF-16字符串。

随后在VB.NET中对此进行了增强,以支持Unicode API调用。但是,我认为VBByRefStr常量表明在.NET中完成的编组必须完全遵循VB6中的方法。

如果您想要UnmanagedType.LPWStr的标准编组,请使用属性。