1

c++ から 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);

ただし、最初のシンボルのみが渡されます: name[0] == 'S'。他のシンボルはヌルです。ここで何が問題なのか教えていただけますか?

ありがとう、ジェーニャ

4

2 に答える 2

2

関数が Unicode 文字列を使用していることを pinvoke マーシャラーに伝えるのを忘れました。デフォルトは CharSet.Ansi です。明示的に CharSet.Unicode を使用する必要があります。修理:

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

「S」の utf-16 エンコード値は 1 文字の C 文字列のように見えるため、単一の「S」が得られます。

一般に、「20」のようなマジック ナンバーは避けてください。文字列バッファの長さを示す引数を追加するだけです。そうすれば、GC ヒープが誤って破損することはありません。StringBuilder.Capacity を渡します。また、成功を示すことができる戻り値を関数に与えて、小さすぎるバッファも無視しないようにします。

于 2013-05-15T17:14:57.020 に答える
0

よくわかりませんが、StringBuilder を使用する代わりに、C# char (wchar) 配列から C++ に渡し、それを埋めてから、C# でこの配列を操作します。

于 2013-05-15T17:07:33.700 に答える