C#でC++のDLLから文字列を受け取る


ご回答いただけると幸いです。

C++で文字列(英数字混在)をcharでreturnする関数を書き、  
C#からその関数を利用し、文字列を受け取ろうと考えています。  
調べてみたところ、C#から文字列を渡すような手順はあっても、  
C++の方から戻す方法が見つからず、困り果てております。  
どなたか、ご存知の方がいらっしゃれば、お教えいただけないでしょうか。




C/C++ で「関数が文字列を返す」というアクションは２つのパターンがあって  
１．呼ばれる関数が `malloc()` 等で動的にメモリを取り、そこに文字列を格納する (`strdup`)  
２．呼ぶ側の関数が固定長のバッファを取り、呼ばれる関数がそこに文字列を格納する (`snprintf`)  
今回の事案はどっちでしょう。

後者であれば `StringBuilder` が使えます。これなら unsafe 不要で、エンコーディング変換も自動。

C++ 側

[code]

    extern "C" __declspec(dllexport) bool __stdcall GetText(char* buf, size_t bufsize) {
        if (bufsize<4) return false
        buf[0]='a';
        buf[1]='\x82'; // 82a0 = CP932 の 'あ'
        buf[2]='\xa0';
        buf[3]='\0';
        return true;
    }
    
[/code]

C# 側

[code]

    [DllImport("example.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
    static extern Boolean GetText(StringBuilder s, Int32 bufsize);
    
    // CharSet.Ansi は OS の標準現地固有エンコーディングを UTF-16 に自動変換する指定
    // 日本語 OS の場合 CP932 → UTF-16
    System.Text.StringBuilder sb = new System.Text.StringBuilder(256);
    GetText(sb, sb.Capacity);
    Console.WriteLine(sb.ToString()); // aあ
    
[/code]

前者の場合 `malloc()` 系の結果をいつどうやって `free()` するかによって話が違い  
C/C++ 側の仕様というか実装というかを見ないと答えが出せません。

