Взаимодействовать вопрос о StringBuilder - PullRequest
2 голосов
/ 18 августа 2010

Я вызываю метод 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!
}

Но если я использую Stringвместо StringBuilder, как показано ниже в моем объявлении метода C #, 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 ()

не наоборот.

Я проверял arg в обратном вызове (StringBuilder arg) , Длина, MaxCapacity, Capacity все одинаковы для char * p или msg [].Только то, что * p приводит к исключению.Почему?

1 Ответ

1 голос
/ 18 августа 2010

Когда вы используете String в качестве типа параметра, CLR не будет пытаться записать какие-либо изменения обратно в собственный буфер памяти. Когда вы используете StringBuilder (который является правильным выбором для входных / выходных строковых параметров), он будет. Но память, на которую указывает p, будет доступна только для чтения из-за того, как вы ее объявили, поэтому вы получите ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...