【问题标题】:Interop question about StringBuilder关于 StringBuilder 的互操作问题
【发布时间】:2010-08-18 09:29:37
【问题描述】:

我正在从 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--->callback()

不是相反。

我检查了callback(StringBuilder arg)中的argLength、MaxCapacity、Capacity对于char *p都是一样的或味精[]。只有 *p 会导致异常。为什么?

【问题讨论】:

  • “我正在从 C 代码调用 C# 方法。” - 一个问题,为什么? :)
  • 我对 C++ 了解不多,但是您在 C++ 应用程序中对 p_func 的定义是什么? StringBuilder 被编组为特殊情况...
  • @Matthew p_func 是一个委托,用于表示名为 callback() 的方法。

标签: c# .net interop marshalling managed


【解决方案1】:

当您使用 String 作为参数类型时,CLR 不会尝试将任何更改写回本机内存缓冲区。当您使用 StringBuilder (这是输入/输出字符串参数的正确选择)时,它会。但是由于您声明它的方式,p 指向的内存将是只读的,这就是您收到错误的原因。

猜你喜欢
  • 2012-10-16
  • 2011-04-13
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多