我从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#方法声明中使用String而不是StringBuilder,则f(p)和f(msg)都可以工作。为什么呢?
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void p_func(String arg);
public static void callback(String arg)
{
Console.WriteLine(arg.ToString());
}
调用逻辑是这样的:
c_method()---->委托p_func --->回调()
不是相反的。
我检查了回调(StringBuilder arg)中的 arg , Length,MaxCapacity,Capacity 对于char * p都是一样的或者msg []。只有* p导致异常。为什么呢?
答案 0 :(得分:1)
当您使用String作为参数类型时,CLR将不会尝试将任何更改写回本机内存缓冲区。当你使用StringBuilder(它是输入/输出字符串参数的正确选择)时,它会。但是内存p指向的只是因为你声明它的方式是只读的,这就是你得到错误的原因。