トップ回答者
C++でポインターのポインターを引き数に持つ関数のラッパーはどう書けば良いでしょうか?

質問
回答
-
これは文字列定数へのポインタを返しているので、C# では扱えません。メモリブロックとして受け取って文字列を生成することになります。ラッパーを作成するとすれば、こんなかんじでしょうか。
public static string GetFileName() { IntPtr p; FileNameGet(out p); // CHAR なら Ansi, WCHAR なら Uni, TCHAR なら Auto return Marshal.PtrToStringAnsi(p); } [DllImport(...)] private static extern void FileNameGet(out IntPtr FileName);
すべての返信
-
C#で、stringの変数を定義して利用します。
ちなみに、同じような目的の関数で引数が配列の下記のような関数
void abcPathGet( char Path[] )
がありますが、[DllImport("abcDLL", EntryPoint = "abcPathGet")]
private static extern void abcPathGet(StringBuilder Path);
public static void PathGet(out string Path)
{
StringBuilder PathBuiler = new StringBuilder(260);
abcPathGet(PathBuiler);
Path = PathBuiler.ToString();
}のようなラッパーを作って利用しています。
同じような利用の仕方をしたいと思います。 -
どう利用したいかではなく、dll がどういう利用方法を想定しているかが問題です。
特にポインタを返してくる場合、呼び出し先で確保された(かもしれない)どう解放するかが問題になります。戻されたポインタを SysFreeString または CoTaskMemFree で解放すればいいのなら 適切な MarshalAs 属性を付けた上で out string で受け取ればいいですが、それ以外の解放手段が必要か、または解放してはいけないのなら out IntPtr で受け取った上で Marshal.PtrToString*** などを使用する必要があります。
-
あ、やっぱりクサキさんの変身は私の質問には答えられていないと読むべきですかね。
そんなに難しい質問なのかなぁ…。でも他の人にも同じように確認しても答えられないこともありました。メモリ確保をどちらが行うか、ましてやメモリ解放などする気は全くない、というのが流行りなのかな?
-
これは文字列定数へのポインタを返しているので、C# では扱えません。メモリブロックとして受け取って文字列を生成することになります。ラッパーを作成するとすれば、こんなかんじでしょうか。
public static string GetFileName() { IntPtr p; FileNameGet(out p); // CHAR なら Ansi, WCHAR なら Uni, TCHAR なら Auto return Marshal.PtrToStringAnsi(p); } [DllImport(...)] private static extern void FileNameGet(out IntPtr FileName);