Zheden
Zheden

Reputation: 593

Passing string from c++ to c#

I'm trying to pass string from c++ to c#.

C++:
extern "C" __declspec(dllexport) void GetSurfaceName(wchar_t* o_name);

void GetSurfaceName(wchar_t* o_name)
{
  swprintf(o_name, 20, L"Surface name");
}

C#:
[DllImport("SurfaceReader.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void GetSurfaceName(StringBuilder o_name);

StringBuilder name = new StringBuilder(20);
GetSurfaceName(name);

But only first symbol is passed: name[0] == 'S'. Other symbols are nulls. Could you tell me what is wrong here?

Thanks, Zhenya

Upvotes: 1

Views: 3419

Answers (2)

Hans Passant
Hans Passant

Reputation: 941307

You forgot to tell the pinvoke marshaller that the function is using a Unicode string. The default is CharSet.Ansi, you'll need to use CharSet.Unicode explicitly. Fix:

[DllImport("SurfaceReader.dll", 
           CallingConvention = CallingConvention.Cdecl, 
           CharSet = CharSet.Unicode)]
private static extern void GetSurfaceName(StringBuilder o_name);

You'll get a single "S" now because the utf-16 encoded value for "S" looks like a C string with one character.

Do in general avoid magic numbers like "20". Just add an argument that say how long the string buffer is. That way you'll never corrupt the GC heap by accident. Pass the StringBuilder.Capacity. And give the function a return value that can indicate success so you also won't ignore a buffer that's too small.

Upvotes: 2

Martin Perry
Martin Perry

Reputation: 9527

I am not sure, but instead of using StringBuilder, I would pass from C# char (wchar) array to C++, fill it and then operate with this array in C#.

Upvotes: 0

Related Questions