博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Marshal.AllocHGlobal VS Marshal.AllocCoTaskMem, Marshal.SizeOf VS sizeof()
阅读量:2439 次
发布时间:2019-05-10

本文共 2743 字,大约阅读时间需要 9 分钟。

http://stackoverflow.com/questions/1887288/marshal-allochglobal-vs-marshal-alloccotaskmem-marshal-sizeof-vs-sizeof

A Windows program always has at least two heaps in which unmanaged memory is allocated. First is the default process heap, used by Windows when it needs to allocate memory on behalf of the program. The second is a heap used by the COM infrastructure to allocate. The .NET P/Invoke marshaller assumes this heap was used by any unmanaged code whose function signature requires de-allocating memory.

AllocHGlobal allocates from the process heap, AllocCoTaskMem allocates from the COM heap.

Whenever you write unmanaged interop code, you should always avoid a situation where code that allocates unmanaged memory is not the same as the code that frees it. There would be a good chance that the wrong de-allocator is used. This is especially true for any code that interops with a C/C++ program. Such programs have their own allocator that uses its own heap, created by the CRT at startup. De-allocating such memory in other code is impossible, you can't reliably get the heap handle. This is a very common source of P/Invoke trouble, especially because the HeapFree() function in XP and earlier silently ignore requests to free memory that wasn't allocated in the right heap (leaking the allocated memory) but Vista and Win7 crash the program with an exception.

No need to worry about this in your case, the mmsystem API functions you are using are clean. They were designed to ensure the same code that allocates also deallocates. This is one reason you have to call waveInPrepareHeader(), it allocates buffers with the same code that ultimately deallocates them. Probably with the default process heap.

You only need to allocate the WAVEHDR structure. And you are responsible for releasing it when you're done with it. The mmsystem APIs don't do it for you, most of all because they cannot do so reliably. Accordingly, you can use either allocator, you just need to make sure to call the corresponding free method. All Windows APIs work this way. I use CoTaskMemAlloc() but there really isn't a preference. Just that if I'm calling badly designed code, it is slightly likelier to use the COM heap.

You should never use sizeof() in an interop scenario. It returns the managed size of value type. That might not be the same after the P/Invoke marshaller has translated a structure type according to the [StructLayout] and [MarshalAs] directives. Only Marshal.SizeOf() gives you a guaranteed correct value.


UPDATE: there was a big change in VS2012. The C runtime library included with it now allocates from the default process heap instead of using its own heap. Long term, that makes AllocHGlobal the most likely avenue for success.

转载地址:http://dhrmb.baihongyu.com/

你可能感兴趣的文章
黑盒子:在理论与现实之间 (转)
查看>>
Microsoft Office XP 智能标记的安装和安全性 (转)
查看>>
A Brief Look at C++ 中文版 (转)
查看>>
令人困惑的return by value (转)
查看>>
在VC中调用WORD(显示,修改,存盘,运行宏) (转)
查看>>
Win32 多线程的性能(2) (转)
查看>>
在Oralce9i内向给定的表对象内插入实际的行 (转)
查看>>
下一版本Windows® CE 开发工具Smart Device Extensions for Microsoft Visual Studio® .NET (转)...
查看>>
GENERATING INTEGER RANDOM NUMBERS(幾種產生隨機數方法的效率分析) (转)
查看>>
什么是JAVA ? (转)
查看>>
绘制位图的问题 (转)
查看>>
程序员,你的逻辑思维有多强(一道推理题测试,不可错过) (转)
查看>>
COM应用软件开发技术 (bcd的文章) (转)
查看>>
JBuilder Editor中光标不能正确定位问题的解决 (转)
查看>>
XML加ASP实现网页“本地化” (转)
查看>>
Java中的异步网络编程 (转)
查看>>
用于核心模式驱动程序的网络体系结构(1) (转)
查看>>
More Effective C++ 条款20 (转)
查看>>
在Weblogic环境下的servlet中实现应用级身份认证 (转)
查看>>
VB程序员眼中的C# 6 (转)
查看>>