关于 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# 方法声明中使用 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()---->delegate p_func--->callback()
而不是相反。
我检查了callback(StringBuilder arg)中的arg,对于char *p或msg[,长度,MaxCapacity,Capacity都是相同的]。只有 *p 才会导致异常。为什么?
I am calling a C# method from C code.
The C# method:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void p_func(StringBuilder arg);
public static void callback(StringBuilder arg)
{
Console.WriteLine(arg.ToString());
}
The C method:
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!
}
But if I use String instead of StringBuilder as below in my C# method declaration, f(p) and f(msg) both work. Why?
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void p_func(String arg);
public static void callback(String arg)
{
Console.WriteLine(arg.ToString());
}
Note
the calling logic is like this:
c_method()---->delegate p_func--->callback()
not the reverse.
I checked the arg in the callback(StringBuilder arg), the Length, MaxCapacity, Capacity are all the same for char *p or msg[]. Only that *p leads to the exception. Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您使用 String 作为参数类型时,CLR 不会尝试将任何更改写回本机内存缓冲区。当您使用 StringBuilder (这是输入/输出字符串参数的正确选择)时,它会的。但是由于您声明它的方式, p 指向的内存将是只读的,这就是您收到错误的原因。
When you use String as the parameter type, the CLR will not attempt to write any changes back to the native memory buffer. When you use a StringBuilder (which is the right choice for in/out string parameters), it will. But the memory p points to will be read-only because of the way you declared it, that's why yout get an error.