Динамическое распределение памяти в родной DLL

У меня есть собственный (неуправляемый) .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 (по крайней мере, в этом проекте), который мне, к сожалению, нужно использовать. Мой вопрос: кто-нибудь знает, почему это вызывает исключение и как его избежать?

3

Решение

new MyClass скорее всего позвонит ::operator new, глобальный оператор, если вы не предоставили MyClass::operator new, И если вы не предоставили ::operator new вы должны получить ::operator new от вашего компилятора (вероятно, Visual Studio).

это ::operator new реализация, вероятно, будет направлена ​​на HeapAlloc, И угадай что? Это та же функция Win32, которую будет вызывать .Net. Здесь не так много волшебства; таким образом Windows назначает страницы памяти вашему виртуальному адресному пространству. И когда вы используете эти страницы, Windows назначит ОЗУ.

Теперь дело в том, что вам не нужно делать ничего особенного для этого. На самом деле, делать что-то особенное, как вы бы перерыв operator new, И так как вы сломали это, вам придется это выяснить. Здесь не так много магического кода. Используйте отладочную сборку, чтобы у вас был чистый дамп стека (без вставки). Можете ли вы вернуться к HeapAlloc?

Проверьте также содержание исключения нарушения прав доступа. Код ошибки будет C0000005. Но что это за исключение? Читать или писать? По какому типу адреса? Код или данные?

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]