了解VB.NET P/Invoke声明中的VBByRefStr
在尝试使用C#中VB.NET程序集中的p/Invoke声明时,我注意到了解VB.NET P/Invoke声明中的VBByRefStr,.net,vb.net,pinvoke,marshalling,.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(...)
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);
我读到:“VBByRefStr:一个值,它使Visual Basic.NET能够更改非托管代码中的字符串,并使结果反映在托管代码中。此值仅支持平台调用。这是Visual Basic中ByVal字符串的默认值。”
我还是不明白。为什么C#中只有
string lpValueName
(参见-edit:for正如不信者Damien#u所指出的,签名与之相同)而在VB.NET中却是奇怪的VBByRefStr
?我应该在VB.NET中使用
声明以避免在C#中使用ref
?或者这是否有任何不利影响?这是为了与VB6 Declare语句向后兼容
当使用ByVal x作为字符串时,您表示希望将VB UTF-16“字符串”类型转换为ASCII表示形式,将指向该ASCII缓冲区的指针传递给该参数,并在调用成功后,将该缓冲区的内容转换回原始UTF-16字符串
随后在VB.NET中对其进行了增强,以支持Unicode API调用。但是,我可以想象VBByRefStr常量指示在.NET中完成的封送必须完全遵循VB6中的方法
如果您想要UnmanagedType.LPWStr的标准封送,那么请使用属性。这并不是说它有很大不同,而是您的pinvoke链接指向不同的函数<代码>RegDeleteKey!=<代码>RegDeleteValue。我在advapi32My bad中找不到的PInvoke页面,看起来我在PInvoke上找到了
RegDeleteKey
,但没有找到RegDeleteValue
。很抱歉给你带来了困惑。不过,主要观察结果与RegDeleteKey
相同:-)有道理,感谢您的解释!我想我应该彻底摆脱VB6风格的Declare
语句,改用DllImport