2


1

StringBuilderに関する相互運用性の質問

CコードからC#メソッドを呼び出しています。

C#メソッド:

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void p_func(StringBuilder arg);

    public static void callback(StringBuilder arg)
    {
        Console.WriteLine(arg.ToString());
    }

Cメソッド:

extern "C" void  c_method(p_func f)
{
 char msg[4];
 ::strcpy(msg,"123");
 char* p="123";
 f(msg); // this is ok
    f(p);   //Error: Attempted to read or write protected memory!
}

しかし、C#メソッドの宣言でStringBuilderではなくStringを使用すると、f(p)とf(msg)の両方が機能します。 Why?

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void p_func(String arg);

    public static void callback(String arg)
    {
        Console.WriteLine(arg.ToString());
    }

Note

呼び出しロジックは次のとおりです。

c_method()---→デリゲートp_func --→ callback()

逆ではありません。

_callback(StringBuilder arg)_の_arg_をチェックしました。_Length、MaxCapacity、Capacity_はすべてchar * pまたはmsg []で同じです。 * pのみが例外につながります。 Why?

1 Answer


1


パラメータータイプとして文字列を使用すると、CLRは変更をネイティブメモリバッファーに書き戻そうとしません。 StringBuilder(in / out文字列パラメーターの正しい選択)を使用すると、それが使用されます。 ただし、pが指すメモリは、宣言した方法のために読み取り専用になります。そのため、エラーは発生しません。