为什么c#和VB.NET隐式地以不同的方式封送char*
本文关键字:方式封 char VB NET 为什么 | 更新日期: 2023-09-27 18:11:17
我有一个用c++编写的函数,它看起来像这样…
extern "C" __declspec(dllexport) int __stdcall SomeFunction(char *theData)
{
// stuff
}
…我在我目前的项目中使用它(用c#编写)。还有其他使用VB编写的此函数的项目,如下所示:
Public Declare Function SomeFunction Lib "MyDLL.dll" _
Alias "_SomeFunction@4" (ByVal theData As String) As Integer
所以我试着用c#写一个等价的,但发现使用字符串类型实际上并不适合我——字符串将返回与我传递给它的相同的数据。我尝试使用"ref string"
代替通过引用传递字符串,我得到了内存访问冲突。
在做了一些挖掘之后,我发现这是c#中正确的实现:
[DllImport("MyDLL.dll", EntryPoint = "_SomeFunction@4")]
public static extern int SomeFunction(StringBuilder theData);
现在我知道了VB。. NET和c#有很大的不同,但我想我一直认为字符串就是字符串。如果一种语言可以隐式地将char*
编组到String
,为什么另一种语言不能,需要完全不同的类?
(为清晰起见编辑了标题)
现在我知道了VB。NET和c#有很大的不同,但我想我一直认为字符串就是字符串
字符串在。net中是不可变的。问问自己,为什么传递不可变数据类型的ByVal
会导致值改变。这不会发生在正常的函数中,只发生在Declare
中。
我猜这一切都与维护一些向后兼容性从经典VB6 Declare
语句是这样做的。在我看来,害群之马是VB.net代码,而不是c#代码。
因为是不同的语言。VB。NET可以做很多c#由于很多原因不能做的事情。老实说,我看不出有什么问题。
我应该补充一下,你可以简单地使用ref char[],它就可以工作了。我看到的一个问题是你的调用约定不匹配。
所以这也可能是你得到内存异常错误的原因
由于string一开始是不可变的,我猜VB以某种方式向导调用以允许函数修改缓冲区。也许VB内部实际上也传递了一个StringBuilder。
如果这是VB团队为了使API调用更像vb6而设计的调用,我不会感到惊讶。