何时使用CoTaskMemAlloc是否合适?有人能举个例子吗?
答案 0 :(得分:19)
将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;
}
Since .NET uses CoTaskMemFree,您必须像这样分配字符串,不能使用malloc / new在堆栈或堆上分配它。
答案 1 :(得分:12)
天哪,我不得不考虑一下这个问题 - 我已经用ATL进行了大量的小规模COM编程,而且很少使用它。
有一种情况可以想到:Windows Shell extensions。如果您正在处理一组文件系统对象,则可能需要处理PIDLs(指向ID列表的指针)。这些是奇怪的小文件系统对象抽象,需要使用COM感知分配器(如CoTaskMemAlloc
)显式分配/解除分配。还有一个替代方法,IMalloc
接口指针从SHGetMalloc
(已弃用)或CoGetMalloc
获得 - 它只是一个要使用的抽象层,因此您的代码不依赖于特定的内存分配器,可以使用任何适当的内存分配器。
使用CoTaskMemAlloc
或IMalloc
而非malloc()
的关键是内存分配/解除分配需要是“支持COM的”,因此它的分配和释放是在运行时始终执行,即使分配和释放由完全不相关的代码完成(例如,Windows分配内存,将其传输到您的C ++代码,后来解除分配,或者您的C ++代码分配,将其转移到其他人的VB代码,稍后解除分配)。 malloc()
和new
都无法与系统的运行时堆进行互操作,因此您无法使用它们来分配内存以传输到其他COM对象,或者从其他COM对象接收内存并取消分配
答案 2 :(得分:7)
This MSDN article比较了Win32公开的各种分配器,包括CoTaskMemAlloc。它主要用于COM编程 - 最具体的是当COM服务器的实现需要分配内存以返回给客户端时。如果您没有编写COM服务器,那么您可能不需要使用它。
(但是,如果您调用使用CoTaskMemAlloc分配内存的代码并将其返回给您,则需要使用CoTaskMemFree释放返回的分配。)
答案 3 :(得分:3)
没有太多可能出错的因为以下调用都以相同的分配结束:
CoTaskMemAlloc/SHAlloc -> IMalloc.Alloc -> GlobalAlloc(GMEM_FIXED)
只有当你使用像malloc()
这样的非Windows(编译器库)调用时才会出错。
官方应该使用CoTaskMemAlloc
进行COM调用(比如分配FORMATETC.ptd字段)
CoTaskMemAlloc
等于GlobalAlloc()
将保持这种状态'直到剪贴板api与com STGMEDIUM看到永恒。 STGMEDIUM使用剪贴板结构和方法,而STGMEDIUM是com,因此CoTaskMemAlloc,剪贴板apis规定GlobalAlloc()
答案 4 :(得分:2)
CoTaskMemAlloc与malloc相同,只是前者用于分配跨进程边界使用的内存。
,即如果我们有两个进程,process1和process2,则假定process1是一个COM服务器,而process2是一个COM客户端,它使用process1公开的接口。 如果process1必须发送一些数据,那么他可以使用CoTaskMemAlloc分配内存来分配内存并复制数据。 process2可以访问该内存位置。
COM库自动进行编组和解组。