CoTaskMemAlloc的用法?

时间:2008-12-26 05:26:56

标签: windows winapi com

何时使用CoTaskMemAlloc是否合适?有人能举个例子吗?

5 个答案:

答案 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获得 - 它只是一个要使用的抽象层,因此您的代码不依赖于特定的内存分配器,可以使用任何适当的内存分配器。

使用CoTaskMemAllocIMalloc而非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库自动进行编组和解组。