PInvoke char* in C DLL handled as String in C#. Issue with null characters

时间秒杀一切 提交于 2019-11-29 09:39:24
David Heffernan

Your marshalling of the output string is incorrect. Using string in the p/invoke declaration is appropriate when passing data from managed to native. But you cannot use that when the data flows in the other direction. Instead you need to use StringBuilder. Like this:

[DllImport(...)]
public static extern int my_Funct(string input, StringBuilder output);

Then allocate the memory for output:

StringBuilder output = new StringBuilder(256);
//256 is the capacity in characters - only you know how large a buffer is needed

And then you can call the function.

int retval = my_Funct(inputStr, output);
string outputStr = output.ToString();

On the other hand, if these parameters have null characters in them then you cannot marshal as string. That's because the marshaller won't marshal anything past the null. Instead you need to marshal it as a byte array.

public static extern int my_Funct(
    [In] byte[] input, 
    [Out] byte[] output
);

That matches your C declaration.

Then assuming the ANSI encoding you convert the input string to a byte array like this:

byte[] input = Encoding.Default.GetBytes(inputString);

If you want to use a different encoding, it's obvious how to do so.

And for the output you do need to allocate the array. Assuming it's the same length as the input you would do this:

byte[] output = new byte[input.Length];

And somehow your C function has got to know the length of the arrays. I'll leave that bit to you!

Then you can call the function

int retval = my_Funct(input, output);

And then to convert the output array back to a C# string you use the Encoding class again.

string outputString = Encoding.Default.GetString(output);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!