gpt4 book ai didi

c# - native dll 中的动态内存分配

转载 作者:太空狗 更新时间:2023-10-29 22:55:56 25 4
gpt4 key购买 nike

我有一个用 C++ 编写的 native (非托管).dll,将从托管进程(C# 程序)调用。在调试 dll 时,我发现的问题是,当我使用 new 关键字在 dll 中创建一个对象时,我得到了系统访问冲突异常。这仅在从托管进程调用 dll 时显示,而不是在我从另一个 native 程序调用它时显示。

代码是这样的:

// 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
}

我知道这与 native 进程试图在允许的内存空间之外分配内存有关。只有在使用 new (至少在这个项目中)分配内存时才会发生,不幸的是,我确实需要使用它。我的问题是:有谁知道为什么会导致异常以及如何避免异常?

最佳答案

new MyClass 很可能会调用全局运算符 ::operator new,除非您提供了 MyClass::operator new .如果您自己没有提供 ::operator new,您应该从编译器(可能是 Visual Studio)中获取 ::operator new

这个::operator new 实现可能会转发给HeapAlloc。你猜怎么着?这与 .Net 也会调用的 Win32 函数相同。这里没有太多魔法;这就是 Windows 将内存页分配给虚拟地址空间的方式。当您使用这些页面时,Windows 将分配 RAM。

现在这里的事情是你不需要为此做任何特别的事情。事实上,做任何特别的事情都会破坏 operator new。既然你把它弄坏了,你就得想办法解决这个问题。这里没有太多神奇的代码。使用调试版本,因此您将拥有清晰的堆栈转储(无内联)。你能回溯到 HeapAlloc 吗?

同时检查访问冲突异常的内容。错误代码将为 C0000005。但它是什么类型的异常呢?读还是写?在什么类型的地址?代码还是数据?

关于c# - native dll 中的动态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49774071/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com