简体   繁体   English

C#使用的本机C ++库的内存分配器

[英]Memory allocators for a native C++ library to be used by C#

I'm writing some native C++ code which needs to be called from C# (and I can't replace the C++ native code with C# code). 我正在编写一些需要从C#调用的本地C ++代码(而且我无法用C#代码替换C ++本地代码)。

I found memory corruptions while allocating/deallocating some memory in the native C++ code using malloc/free. 我在使用malloc / free分配/取消分配本机C ++代码中的某些内存时发现内存损坏。 Then I used LocalAlloc/LocalFree and HeapAlloc/HeapFree and had the same problems. 然后,我使用了LocalAlloc / LocalFree和HeapAlloc / HeapFree,并遇到了相同的问题。

The allocations/deallocations seem to be correct, and they happen in a separate thread, created by the native code. 分配/取消分配似乎是正确的,它们发生在由本机代码创建的单独线程中。

I was wondering which is the best allocation strategy to use in a native C++ library called by C# 我想知道哪种是在C#调用的本机C ++库中使用的最佳分配策略

EDIT: found the problem: the problem wasn't in the allocation/deallocation code, but in some memory being written after being deallocated. 编辑:发现了问题:问题不在分配/解除分配代码中,而是在释放后写入的某些内存中。

As long as the C# side of the code uses the compiler's /unsafe switch and the fixed keyword used for holding the buffer of data, I think you should be ok. 只要代码的C#端使用编译器的/unsafe开关和用于保存数据缓冲区的fixed关键字,我认为您就可以了。

As to the question of your memory allocation, it may not be the C++ memory allocation code that is causing the problem, it could be the way how the C++ code is interacting with the driver...maybe using VirtualAlloc / VirtualFree pair as per the MSDN docs... 至于您的内存分配问题,可能不是导致问题的C ++内存分配代码,可能是C ++代码与驱动程序交互的方式...也许按照以下方式使用VirtualAlloc / VirtualFree对: MSDN文档...

Edit: When you try to allocate the buffer to hold the data from the C++ side after interacting with the driver...possibly a race-condition or interrupt latency is causing a memory corruption...just a thought... 编辑:当您尝试分配缓冲区以与驱动程序进行交互后从C ++端保存数据时...竞争条件或中断延迟可能会导致内存损坏...只是一个想法...

Hope this helps, Best regards, Tom. 希望这对您有所帮助,汤姆,谢谢。

Your question is missing essential details, it isn't at all clear whether the memory allocated by the C++ code needs to be released on the C# side. 您的问题缺少基本细节,还不清楚是否需要在C#端释放C ++代码分配的内存。 That's normally done automatically with, say, the P/Invoke marshaller or the COM interop layer in the CLR. 通常,这是使用CLR中的P / Invoke编组器或COM互操作层自动完成的。 Or can be done manually by declaring a method argument as IntPtr, then use of the Marshal class. 或者可以通过将方法参数声明为IntPtr,然后使用Marshal类来手动完成。

If it is done automatically you must use the COM memory allocator, CoTaskMemAlloc(). 如果自动完成,则必须使用COM内存分配器CoTaskMemAlloc()。 If you marshal yourself you could also use GlobalAlloc(), release on the C# side with Marshal.FreeHGlobal(). 如果您自己编组,则也可以使用GlobalAlloc(),并通过Marshal.FreeHGlobal()在C#一侧发布。 There isn't any advantage to using GlobalAlloc(), you might as well use CoTaskMemAlloc() and release with Marshal.FreeCoTaskMem(). 使用GlobalAlloc()没有任何优势,您最好使用CoTaskMemAlloc()并与Marshal.FreeCoTaskMem()一起发布。

But you should have noticed this yourself. 但是您应该自己注意到这一点。 Allocating with malloc() or HeapAlloc() on the C++ side causes leaks instead of corruption if the managed code releases the memory. 如果托管代码释放内存,则在C ++端使用malloc()或HeapAlloc()分配将导致泄漏而不是损坏。 Vista and Win7 have a much stricter heap manager, it terminates the program if it notices a bad release. Vista和Win7具有更严格的堆管理器,如果发现发行错误,它将终止程序。

It sounds to me that you have simple heap corruption in your C++ code. 在我看来,您的C ++代码中有简单的堆损坏。 That is the most common scourge of unmanaged C++ programming, over-running the end of a buffer, writing to memory that's been freed, bad pointer values. 这是非托管C ++编程最常见的祸害,即溢出缓冲区的末端,写到已释放的内存,错误的指针值。 The way to get rid of bugs like these is a careful code review and use of a debug allocator, such as the one provided by <crtdbg.h> . 消除此类错误的方法是仔细检查代码并使用调试分配器,例如<crtdbg.h>提供的调试分配器。 Good luck with it. 祝你好运。

The windows driver developpement kit recommend against the use of C++ for drivers. Windows驱动程序开发工具包建议不要将C ++用于驱动程序。

Also the best strategy is to have the driver manage its own memory. 最好的策略也是让驱动程序管理自己的内存。 When the c# needs to see the data then pass it a marshalled buffer and have the driver to fill it 当C#需要查看数据时,然后将其传递给编组的缓冲区并让驱动程序填充它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM