开发者

Why do C# and VB.NET implicitly marshal char* differently?

开发者 https://www.devze.com 2023-04-12 09:20 出处:网络
So I have a function, written in C++, that looks like this... extern \"C\" __declspec(dllexport) int __stdcall SomeFunction(char *theData)

So I have a function, written in C++, that looks like this...

extern "C" __declspec(dllexport) int __stdcall SomeFunction(char *theData)
{
    // stuff
}

... and I'm using it in my current project (written in C#). There are other projects that use this function written in VB, looking like this:

Public Declare Function SomeFunction Lib "MyDLL.dll" _
    Alias "_SomeFunction@4" (ByVal theData As String) As Integer

So I tried writing an equivalent in C#, but found that using the string type didn't actually work for me - the string would come back with the same data I passed it in with. I tried开发者_如何学Go using "ref string" instead to pass the string by reference and I got a memory access violation.

After doing some digging, I found that this was the correct implementation in C#:

[DllImport("MyDLL.dll", EntryPoint = "_SomeFunction@4")]
public static extern int SomeFunction(StringBuilder theData);

Now I know that VB.NET and C# are quite different, but I suppose I always assumed that strings were strings. If one language can marshal char* to String implicitly, why can't the other, requiring a different class altogether?

(edited the title for clarity)


Now I know that VB.NET and C# are quite different, but I suppose I always assumed that strings were strings

Strings are immutable in .net. Ask yourself why it is that ByVal passing of an immutable data type can result in the value changing. That doesn't happen for normal functions, just for Declare.

I'd guess it all has to do with maintaining some backwards compatibility with Declare statements from classic VB6 which were done this way. To my mind the black sheep here is the VB.net code rather than the C# code.


Because they are different languages. VB.NET can a great deal of things that C# cannot for many reasons. I don't see the problem to be honest.

I should add you could have simply did ref char[] and it would have worked. One problem I see is that your calling conventions do not match.

So that also is likely the reason you got a memory exception error.


Since string is immutable to begin with, I'm guessing that VB somehow wizards the call to allow for the buffer to be modified by the function. Perhaps internally VB is actually passing a StringBuilder as well.

I wouldn't be surprised if this was a design call by the VB team to make API calls more VB6-like.

0

精彩评论

暂无评论...
验证码 换一张
取 消