关于 StringBuilder 的互操作问题

发布于 2024-09-14 16:45:51 字数 1058 浏览 8 评论 0原文

我正在从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫九 2024-09-21 16:45:51

当您使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文