2008-12-26 22 views
14

何時適合使用CoTaskMemAlloc?有人可以舉個例子嗎?CoTaskMemAlloc的用法?

+0

我下面貼上,當你可能需要使用CoTaskMemAlloc一些信息,但它可能會有所幫助,爲您提供一些背景爲您的問題... – reuben 2008-12-26 05:54:51

+0

解決了這個問題,它的標題有點。 – mmcdole 2008-12-26 06:09:45

回答

10

天哪,我不得不思考這一段時間 - 我已經用ATL做了大量的小規模COM編程,很少必須使用它。

雖然有一種情況出現在腦海中:Windows Shell extensions。如果您正在處理一組文件系統對象,則可能需要處理PIDLs(指向ID列表的指針)。這些是奇怪的小文件系統對象抽象,它們需要使用COM感知分配器(如CoTaskMemAlloc)進行顯式分配/釋放。還有一個替代方案,從SHGetMalloc(不贊成使用)或CoGetMalloc獲得的IMalloc接口指針 - 它只是一個使用的抽象層,以便您的代碼不受限於特定的內存分配器,並且可以使用任何適當的內存分配器。

使用CoTaskMemAllocIMalloc而不是malloc()的一點是,內存分配/釋放需要的東西,這樣的分配和釋放都是在運行時始終執行的是「COM意識」,即使分配並通過完全不相關的代碼完成取消分配(例如,Windows分配內存,將其傳輸到您的C++代碼,稍後解除分配,或者您的C++代碼分配,將其轉移給其他人的VB代碼,以後再分配)。 malloc()new都不能與系統的運行時堆進行互操作,因此您不能使用它們分配內存來傳輸到其他COM對象,或從其他COM對象接收內存並釋放內存。

7

This MSDN article比較了Win32公開的各種分配器的一些,包括CoTaskMemAlloc。它主要用於COM編程 - 特別是當COM服務器的實現需要分配內存返回給客戶端時。如果你不寫COM服務器,那麼你可能不需要使用它。

(不過,如果你調用使用CoTaskMemAlloc分配內存,並返回回給你的代碼,你需要釋放使用CoTaskMemFree返回的分配(一個或多個)。)

+0

謝謝Reuben, 我的要求是從comserver的進程中分配內存 - >從comclient側做同樣的realloc,這又是一個不同的過程,然後從comserver端釋放它... 我希望我可以使用cotaskmemxxx fns達到相同 - – atVelu 2008-12-26 06:27:33

2

CoTaskMemAlloc與malloc相同,但前者用於分配跨進程邊界使用的內存。

即,如果我們有兩個進程process1和process2,則假定process1是一個COM服務器,而process2是一個使用process1公開的接口的COM Client。 如果process1必須發送一些數據,那麼他可以使用CoTaskMemAlloc分配內存來分配內存並複製數據。 該內存位置可由process2訪問。

COM庫自動執行編組和解組。

18

將字符*從本地C++庫作爲字符串返回到.NET時使用CoTaskMemAlloc。

C#

[DllImport("test.dll", CharSet=CharSet.Ansi)] 
extern static string Foo(); 

Ç

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 /新堆上。

3

確實沒有太多可以去錯了,因爲下面的調用都具有相同的分配結束:

CoTaskMemAlloc/SHAlloc -> IMalloc.Alloc -> GlobalAlloc(GMEM_FIXED) 

只有在使用非Windows(編譯庫)調用像malloc()事情會錯誤。

官方應該使用CoTaskMemAlloc爲COM調用(如分配FORMATETC.ptd場)

CoTaskMemAlloc等於GlobalAlloc()將保持這樣的「直到永遠在剪貼板API與COM STGMEDIUM看到。該STGMEDIUM使用剪貼板的結構和方法,同時STGMEDIUM是COM,因此CoTaskMemAlloc,剪貼板的API規定GlobalAlloc()