我正在 Visual Studio 2010 中创建一个非托管 DLL。
为了测试我的 DLL,我使用 Visual Basic 创建了另一个项目,并将其附加到解决方案中。
VB 代码调用 DLL 中的 InstallHook 函数,传递 VB 处回调函数的委托(delegate)。然后 DLL 创建一个钩子(Hook),每次按下一个键时,都会调用 VB 回调来接收该键和一些其他参数作为参数。
问题是,按下某些键后,VB 回调中的缓冲区达到特定大小,程序崩溃。更具体地说,当最后一次调用回调并将其写入VB中的缓冲区时,就像在某个地方重叠一样,因为下次在DLL中调用回调时,程序崩溃了而没有到达回调(dll中的指针即可)
我不太了解 .Net 的架构,也不知道到底出了什么问题,但我对我所做的代码非常有信心,问题应该是 .Net 中内存管理的技术问题。
编辑:我忘了说,如果我从 VB 代码中调用回调,那么它就可以正常工作。通常从安装在同一窗口中的 WndProc 调用回调。
谢谢......
最佳答案
the pointer in the dll is fine
我怀疑这就是问题所在。如果将地址传递到 native 例程中,然后在单个方法调用的范围之外使用它,则会面临一些风险。
问题在于 .NET 使用压缩垃圾收集器。这意味着运行时可能会在方法调用之间将缓冲区“移动”到完全不同的位置。因此,在某些时候,当您写入它时,它可能位于完全不同的位置。
您可以通过 Marshal 自行分配和管理内存来解决此问题。类(class)。或者,您可以使用GCHandle class to pin the memory and prevent it from being moved 。
关于.Net 和非托管 dll -> 内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8108432/