Всякий раз, когда я использую одну функцию из неуправляемой dll в Usercontrol, я получаю эту ошибку. «System.AccessViolationException: попытка чтения или записи защищенной памяти. Часто это указывает на то, что другая память повреждена». Но это происходит только в том случае, если я использую эту функцию много раз. Но мне нужно использовать эту функцию каждые 3 минуты. Любые идеи высоко ценятся. Спасибо.
Очистить неуправляемую память
Ответы (2)
Судя по тому, что вы опубликовали с очень небольшим количеством информации, мой первый внутренний ответ будет заключаться в том, что неуправляемая dll, которую вы используете, если она была написана третьей стороной, имеет внутри нее ошибки обработки памяти. Если это включенная DLL-библиотека Windows, вам нужно больше узнать о том, как вы ее используете, или о ресурсах, которые она использует, поскольку эта ошибка, скорее всего, вызвана вашим кодом, если это DLL-библиотека Windows.
Одна вещь, на которую вы должны обратить внимание, - это то, как вы получаете доступ к общим данным между вашей программой и внешней DLL, возможно, некоторые из ваших членов должны быть помечены как volatile и использовать блокировку при их обработке.
Управление памятью на Marshalling — сложная вещь. Вы даете очень мало информации, поэтому я могу ответить только в общем:
Маршаллер Interop использует CoTaskMemFree и CoTaskMemAlloc для выделения памяти. Если ваша DLL выделяет память, а .NET должен ее освобождать (или наоборот), то вы должны использовать эти функции. Если память выделяется с помощью new или malloc() и освобождается с помощью delete или free(), библиотека должна предоставить некоторую функцию Cleanup(), чтобы справиться с этим. Чтобы Marshaller не освобождал память, вы должны объявить свои функции с IntPtr как тип данных параметра/возвращаемого значения вместо использования строки или чего-либо еще.
Рассмотрим эти объявления:
[ DllImport( "Your.dll", CharSet=CharSet.Auto )]
public static extern string GetSomeString();
[ DllImport( "Your.dll", CharSet=CharSet.Auto )]
public static extern IntPtr GetSomeString();
Первая функция должна возвращать строку, выделенную с помощью CoTaskMemAlloc(), и она освобождается .NET Marshaller. Вторая функция может вернуть строку, выделенную malloc или delete, но память не освобождается автоматически. Вы должны вызвать какую-то функцию FreeMemory(IntPtr), которую должна предоставить библиотека.
Не забудьте прочитать: Поведение маршалинга .NET по умолчанию