了解 VB.NET P/Invoke 声明中的 VBByRefStr
Understanding VBByRefStr in VB.NET P/Invoke declarations
当尝试使用在 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);
在 MSDN 我读到:
VBByRefStr
: A value that enables Visual Basic .NET to change a string in unmanaged code, and have the results reflected in managed code. This value is supported only for platform invoke. This is default value in Visual Basic for ByVal
strings.
我还是不明白。为什么在C#中只有string lpValueName
(参见pinvoke.net - edit: for RegDeleteKey
as Damien_The_Unbeliever pointed out, signature is the same like RegDeleteValue
),而在VB.NET中却很奇怪VBByRefStr
?我应该在 VB.NET 中用 <MarshalAs(UnmanagedType.LPWStr)>
声明以避免在 C# 中使用 ref
吗?或者这有什么副作用吗?
这是为了向后兼容 VB6 Declare 语句。
当使用 ByVal x As String 时,您表示要将 VB UTF-16 "String" 类型转换为 ASCII 表示形式,将指向该 ASCII 缓冲区的指针传递给该参数,调用成功后,将该缓冲区的内容转换回原始的 UTF-16 字符串。
这随后在 VB.NET 中得到增强,以支持 Unicode API 调用。但是,我想 VBByRefStr 常量表示在 .NET 中完成的编组必须完全遵循 VB6 中的方法。
如果您想要 UnmanagedType.LPWStr 的标准编组,请使用属性。
当尝试使用在 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);
在 MSDN 我读到:
VBByRefStr
: A value that enables Visual Basic .NET to change a string in unmanaged code, and have the results reflected in managed code. This value is supported only for platform invoke. This is default value in Visual Basic forByVal
strings.
我还是不明白。为什么在C#中只有string lpValueName
(参见pinvoke.net - edit: for RegDeleteKey
as Damien_The_Unbeliever pointed out, signature is the same like RegDeleteValue
),而在VB.NET中却很奇怪VBByRefStr
?我应该在 VB.NET 中用 <MarshalAs(UnmanagedType.LPWStr)>
声明以避免在 C# 中使用 ref
吗?或者这有什么副作用吗?
这是为了向后兼容 VB6 Declare 语句。
当使用 ByVal x As String 时,您表示要将 VB UTF-16 "String" 类型转换为 ASCII 表示形式,将指向该 ASCII 缓冲区的指针传递给该参数,调用成功后,将该缓冲区的内容转换回原始的 UTF-16 字符串。
这随后在 VB.NET 中得到增强,以支持 Unicode API 调用。但是,我想 VBByRefStr 常量表示在 .NET 中完成的编组必须完全遵循 VB6 中的方法。
如果您想要 UnmanagedType.LPWStr 的标准编组,请使用属性。