Функции C, которые возвращают строку, являются проблемой управления памятью.Для строки AC требуется массив, и память для этого массива должна быть освобождена после использования строки.Это делает такие функции очень сложными для использования в программе на Си, почти невозможно использовать с pinvoke.Это также классическая ошибка C, возвращающая указатель на строку в стеке.
Пинвоукс маршаллер попытается освободить возвращенную строку, как требуется, чтобы избежать утечки памяти.Он будет использовать CoTaskMemFree ().Это не часто приводит к хорошему завершению, редко, когда код C фактически использует CoTaskMemAlloc для выделения памяти для массива.На XP это приведет к тихой утечке памяти.В Vista и Win7 гораздо более строгие диспетчеры кучи, они будут вызывать разрыв отладки, если подключен неуправляемый отладчик.Затем выполните бомбардировку программы с помощью AccessViolation.
Вы можете избежать поведения автоматического маршалинга, объявив тип возвращаемого значения как IntPtr и выполнить маршалинг строки самостоятельно.Обычно с Marshal.PtrToStringAnsi ().Но тогда вы все еще сталкиваетесь с задачей освобождения памяти.Вы не можете, у вас нет дескриптора кучи CRT, и вы не можете вызвать функцию free ().
C, которые возвращают строки, должны быть объявлены с аргументом, который передает строковый буфер.И аргумент, который говорит, насколько большой буфер.Вот так:
int GetErrorMessage(int errorCode, char* buffer, size_t bufferSize);
Теперь все просто, вызывающая сторона может выделить память для буфера и освободить ее.И функция C просто копирует строку в буфер.Возвращаемое значение можно использовать, чтобы указать, сколько символов было скопировано, или указать, что необходим больший буфер.Не экономьте на аргументе bufferSize
, переполнение буфера смертельно и вызывает страшное исключение FatalExecutionEngineError, исключение, которое можно отладить так же, как AV, так как повреждение кучи GC не обнаруживается намного позже.Вы используете StringBuilder на стороне C #, соответственно инициализированный с ненулевой емкостью.Значение bufferSize.