Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
了解VB.NET P/Invoke声明中的VBByRefStr_.net_Vb.net_Pinvoke_Marshalling - Fatal编程技术网

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

了解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(...)

在尝试使用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);
我读到:“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