什么时候适合使用CoTaskMemAlloc? 有人可以举个例子吗?
天哪,我不得不考虑一下这个 – 我用ATL做了大量小规模的COM编程,很少用到它。
有一种情况,想到的是Windows Shell扩展 。 如果您正在处理一组文件系统对象,则可能需要处理PIDL (指向ID列表的指针)。 这些都是奇怪的小文件系统对象抽象,他们需要使用COM感知的分配器,如CoTaskMemAlloc
显式分配/解除分配。 还有一种替代方法,即从SHGetMalloc
(不建议使用)或CoGetMalloc
获得的IMalloc
接口指针 – 它只是一个抽象层,因此您的代码不会绑定到特定的内存分配器,并可以使用任何适当的内存分配器。
使用CoTaskMemAlloc
或IMalloc
而不是malloc()
的要点是内存分配/释放需要是“COM意识到的”,以便在运行时一致地执行分配和解除分配,即使分配和解除分配完全不相关的代码完成(例如,Windows分配内存,将其传输到您的C ++代码,稍后解除分配,或您的C ++代码分配,将其转移到其他人的VB代码,稍后释放)。 malloc()
和new
都不能与系统的运行时堆互操作,所以你不能使用它们来分配内存来传递给其他COM对象,或者从其他COM对象接收内存并释放内存。
将char *从本机C ++库作为字符串返回到.NET时,请使用CoTaskMemAlloc。
C#
[DllImport("test.dll", CharSet=CharSet.Ansi)] extern static string Foo();
C
char* Foo() { std::string response("response"); int len = response.length() + 1; char* buff = (char*) CoTaskMemAlloc(len); strcpy_s(buff, len, response.c_str()); return buff; }
由于.NET使用CoTaskMemFree ,你必须像这样分配字符串,你不能使用malloc / new分配堆栈或堆。
这篇MSDN文章比较了Win32公开的各种分配器,包括CoTaskMemAlloc。 它主要用于COM编程 – 特别是当COM服务器的实现需要分配内存返回给客户端时。 如果你不写COM服务器,那么你可能不需要使用它。
(但是,如果调用使用CoTaskMemAlloc分配内存的代码并将其返回给您,则需要使用CoTaskMemFree释放返回的分配。)
CoTaskMemAlloc与malloc相同,只是前者用于分配跨越进程边界使用的内存。
即如果我们有两个进程,process1和process2,假设process1是一个COM服务器,而process2是一个使用process1公开的接口的COM客户端。 如果process1必须发送一些数据,那么他可以使用CoTaskMemAlloc分配内存来分配内存并复制数据。 该内存位置可以被process2访问。
COM库自动进行编组和解组。
没有什么可以做错的,因为下面的调用都会得到相同的分配:
CoTaskMemAlloc/SHAlloc -> IMalloc.Alloc -> GlobalAlloc(GMEM_FIXED)
只有当你使用像malloc()
这样的非windows(编译器库)调用时,才会出错。
官方应该使用CoTaskMemAlloc
进行COM调用(如分配一个FORMATETC.ptd字段)
那CoTaskMemAlloc
等于GlobalAlloc()
将保持这种方式,直到永久在剪贴板api与com STGMEDIUM。 STGMEDIUM使用剪贴板结构和方法,而STGMEDIUM是com,因此CoTaskMemAlloc,剪贴板ap规定了GlobalAlloc()