中の技術日誌ブログ

C#とC++/CLIと
VBと.NETとWindowsで戯れる
 

目次

Blog 利用状況

ニュース

自己紹介

東京でソフトウェアエンジニアをやっています。
お仕事大募集中です。
記事執筆や、講師依頼とかでも何でもどうぞ(*^_^*)
似顔絵 MSMVPロゴ
MSMVP Visual C# Since 2004/04-2013/03

記事カテゴリ

書庫

日記カテゴリ

00-整理

01-MSMVP

マーシャラーのせいでメモリを壊される(C#)

LPWSTR WINAPI StringTest(LPWSTR dest )
{
    return dest; }

このようなC++のコードを

[DllImport("hoge.dll", CharSet = CharSet.Unicode)]
static extern String StringTest(StringBuilder dest);

このように呼ぶと、マーシャラーがうまく受け渡し変換してくれます。

IntPtrを使う場合どうでしょう

[DllImport("hoge.dll", CharSet = CharSet.Unicode)]
static extern String StringTest(IntPtr dest);

このような感じにするとdestで渡したエリアをreturnしているので、マーシャラーがStringにうまくコピーしてくれるような気がします。

確かにデバッガで見る限り戻り値はうまく取得できるのですが、destの方が破壊されてしまうために、destを使い回している場合に動かなくなります。

どのような理屈でマーシャラーがdestの領域を壊しているのか分かりませんが、このような動きをする(destを戻すようなCの関数的なメソッド)関数をP/Invokeで呼ぶ場合には注意が必要です。

マーシャラーの関与を排除するためにはStringをIntPtrにします。

[DllImport("hoge.dll", CharSet = CharSet.Unicode)]
static extern IntPtr StringTest(IntPtr dest);

投稿日時 : 2010年10月31日 16:41

コメントを追加

No comments posted yet.
タイトル
名前
URL
コメント