У меня есть собственный (неуправляемый) .dll, написанный на C ++, который должен вызываться из управляемого процесса (программы на C #). При отладке DLL проблема, которую я показал, заключается в том, что, когда я создаю объект в DLL с new
Ключевое слово Я получаю исключение нарушения доступа к системе. Это проявляется только при вызове dll из управляемого процесса, а не когда я вызываю его из другой собственной программы.
Код похож на это:
// Native.dll file
MyClass myInstance; // global variable (and does need to be so)
__declspec(dllexport) uint8_t _stdcall NativeFunction(){
myInstance = new MyClass(); // <-- this causes Access Violation Exception
}
и код C #:
using System.Runtime.Interopservices;
// Loading the dll
[DllImport("Native.dll",CallingConvention = CallingConvention.StdCall)]
private extern static byte NativeFunction();
class TestClass{
byte returnVal = NativeFunction(); //<-- exception in managed context
}
Я знаю, что это как-то связано с нативным процессом, пытающимся выделить память вне допустимого пространства памяти. Это происходит только тогда, когда память выделена new
(по крайней мере, в этом проекте), который мне, к сожалению, нужно использовать. Мой вопрос: кто-нибудь знает, почему это вызывает исключение и как его избежать?
new MyClass
скорее всего позвонит ::operator new
, глобальный оператор, если вы не предоставили MyClass::operator new
, И если вы не предоставили ::operator new
вы должны получить ::operator new
от вашего компилятора (вероятно, Visual Studio).
это ::operator new
реализация, вероятно, будет направлена на HeapAlloc
, И угадай что? Это та же функция Win32, которую будет вызывать .Net. Здесь не так много волшебства; таким образом Windows назначает страницы памяти вашему виртуальному адресному пространству. И когда вы используете эти страницы, Windows назначит ОЗУ.
Теперь дело в том, что вам не нужно делать ничего особенного для этого. На самом деле, делать что-то особенное, как вы бы перерыв operator new
, И так как вы сломали это, вам придется это выяснить. Здесь не так много магического кода. Используйте отладочную сборку, чтобы у вас был чистый дамп стека (без вставки). Можете ли вы вернуться к HeapAlloc
?
Проверьте также содержание исключения нарушения прав доступа. Код ошибки будет C0000005. Но что это за исключение? Читать или писать? По какому типу адреса? Код или данные?
Других решений пока нет …