DLL に次の C 関数があるとします。
char * GetDir(char* path );
この関数を C# に P/Invoke し、char * を適切にマーシャリングするにはどうすればよいでしょうか。.NET は LPCTSTR の実行方法を知っているようですが、この関数を呼び出すときに NotSupportedException を発生させないマーシャリングを理解できない場合。
DLL に次の C 関数があるとします。
char * GetDir(char* path );
この関数を C# に P/Invoke し、char * を適切にマーシャリングするにはどうすればよいでしょうか。.NET は LPCTSTR の実行方法を知っているようですが、この関数を呼び出すときに NotSupportedException を発生させないマーシャリングを理解できない場合。
OregonGhost の答えは、GetDir から返された char* が HGlobal または LocalAlloc に割り当てられている場合にのみ正しいです。どれがどれか思い出せませんが、CLR は、PInvoke 関数からの文字列の戻り値の型がいずれかで割り当てられたと想定します。
より堅牢な方法は、GetDir の戻り値を IntPtr に型指定することです。次に、Marshal.PtrToStringAnsi 関数のいずれかを使用して、文字列型を取得できます。また、選択した方法で文字列を解放する柔軟性も提供します。
[DllImport("your.dll", CharSet = CharSet.Ansi)]
IntPtr GetDir(StringBuilder path);
GetDir の動作について他に何かヒントがあれば教えてください。入力文字列を変更しますか? 返される値はどのように割り当てられますか? 提供していただければ、より適切な回答を差し上げることができます。
試す
[DllImport("your.dll", CharSet = CharSet.Ansi)]
string GetDir(StringBuilder path);
string はゼロで終わる文字列に自動的にマーシャリングされ、CharSet プロパティを使用して、Unicode ではなく ANSI を使用する必要があることを Marshaller に伝えます。注: const char* には string (または System.String) を使用しますが、char* には StringBuilder を使用します。
この例のように、MarshalAs を試すこともできます。