2008-12-26 1 views
14

Wann ist es angebracht, CoTaskMemAlloc zu verwenden? Kann jemand ein Beispiel geben?Verwendung von CoTaskMemAlloc?

+0

Ich habe einige Informationen unten auf, wenn Sie möglicherweise CoTaskMemAlloc benötigen, aber es könnte hilfreich für Sie zur Verfügung stellen Irgendein Kontext für deine Frage ... – reuben

+0

hat die Frage behoben und es ist Titel ein bisschen. – mmcdole

Antwort

10

Gosh, musste ich denken eine Weile für diese eine - ich habe eine ganze Menge kleine COM-Programmierung mit ATL gemacht und selten zu benutzen.

Es gibt jedoch eine Situation, die in den Sinn kommt: Windows Shell extensions. Wenn Sie mit einer Reihe von Dateisystemobjekten zu tun haben, müssen Sie möglicherweise mit PIDLs (Zeiger auf eine ID-Liste) umgehen. Dies sind bizarre kleine Dateisystemobjekt-Abstraktionen, und sie müssen explizit zugewiesen/freigegeben werden, indem ein COM-fähiger Zuordner wie CoTaskMemAlloc verwendet wird. Es gibt auch eine Alternative, den IMalloc Schnittstellenzeiger, erhalten von SHGetMalloc (veraltet) oder CoGetMalloc - es ist nur eine Abstraktionsschicht zu verwenden, so dass Ihr Code nicht an einen bestimmten Speicherzuordner gebunden ist und einen geeigneten verwenden kann.

Der Sinn der Verwendung von CoTaskMemAlloc oder IMalloc statt malloc() ist, dass die Speicherzuweisung/Deallokation etwas sein muss, die „COM-aware“, so dass ihre Zuweisung und Freigabe ist konsistent zur Laufzeit durchgeführt werden, auch wenn die Zuweisung und die Zuordnung erfolgt durch völlig unabhängigen Code (zB Windows reserviert Speicher, überträgt es in Ihren C++ - Code, der später freigibt oder Ihren C++ - Code zuordnet, überträgt ihn an den VB-Code von jemand anderem, der später freigibt). Weder malloc() noch new können mit dem Runtime-Heap des Systems zusammenarbeiten, sodass Sie sie nicht zum Zuweisen von Speicher für die Übertragung zu anderen COM-Objekten oder zum Empfangen von Speicher von anderen COM-Objekten und zum Aufheben der Zuordnung verwenden können.

7

This MSDN article vergleicht einige der verschiedenen Allokatoren von Win32, einschließlich CoTaskMemAlloc. Es wird hauptsächlich in der COM-Programmierung verwendet - insbesondere dann, wenn die Implementierung eines COM-Servers Speicher reservieren muss, um zu einem Client zurückzukehren. Wenn Sie keinen COM-Server schreiben, müssen Sie ihn wahrscheinlich nicht verwenden.

(Wenn Sie jedoch Code aufrufen, CoTaskMemAlloc Speicher mit zuordnet und gibt es zurück zu Ihnen, Sie werden die zurück Zuteilung befreien müssen (s) mit CoTaskMemFree.)

+0

Danke Reuben, Meine Anforderung ist es, Speicher von dem Comserver in Prozess zuweisen -> tun Sie ein Realloc auf dem gleichen von der Comclient-Seite, die wieder ein anderer Prozess ist und dann frei von der Seite des Servers ... Ich hoffe, ich kann Verwenden Sie cotaskmemxxx fns, um dasselbe zu erreichen - – atVelu

2

CoTaskMemAlloc ist dasselbe wie malloc, außer dass mit former Speicherplatz zugewiesen wird, der über Prozessgrenzen hinweg verwendet wird.

Wenn wir zwei Prozesse haben, process1 und process2, nehmen wir an, dass process1 ein COM-Server ist und process2 ein COM-Client, der die von process1 bereitgestellten Schnittstellen verwendet. Wenn process1 einige Daten senden muss, kann er mit CoTaskMemAlloc Speicher reservieren, um den Speicher zuzuweisen und die Daten zu kopieren. Auf diesen Speicherort kann process2 zugreifen.

COM-Bibliothek führt das Marshalling und das Unmarshalling automatisch aus.

18

Verwenden Sie CoTaskMemAlloc, wenn Sie ein Zeichen * aus einer systemeigenen C++ - Bibliothek als Zeichenfolge an .NET zurückgeben.

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, können Sie die Zeichenfolge wie folgt zuordnen, können Sie es nicht auf dem Stapel zuweisen oder dem Heap mit malloc/neu.

+0

Wann wird die von 'Foo()' zurückgegebene Ressource freigegeben? Oder sollte das manuell gemacht werden? –

+0

@ChielenBrinke CLR folgt den gleichen GC-Regeln für die Ressource wie für alle anderen verwalteten Ressourcen. – zz3599

+0

@ zz3599 was bedeutet das? Die CLR muss alle Verweise auf diesen Speicher kennen. Aber zum Zeitpunkt des Aufrufs von CoTaskMemAlloc befinden wir uns immer noch in nicht verwaltetem Code. Soweit die CLR weiß, gibt es keine Referenzen auf diesen Speicher. Aber das würde bedeuten, dass diese Erinnerung direkt nach ihrer Zuweisung gesammelt werden könnte, was nicht der Fall ist, wie ich annehme, da es dieses Beispiel ungültig machen würde. Die Frage ist: Wie funktioniert es dann? –

3

gibt es nicht wirklich viel, was schief gehen kann, wie die folgenden Anrufe alle mit der gleichen Zuteilung am Ende:

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

nur, wenn Sie nicht-Fenster (Compiler-Bibliothek) verwenden ruft wie malloc() Dinge gehen falsch.

Offiziell sollte man CoTaskMemAlloc verwenden für COM-Aufrufe (wie ein FORMATETC.ptd Feld Zuteilung)

Das CoTaskMemAllocGlobalAlloc() gleich wird auf diese Weise ‚bleiben bis in alle Ewigkeit im Vergleich com STGMEDIUM in die Zwischenablage api zu sehen ist. Das STGMEDIUM verwendet die Zwischenablage Strukturen und Methode und während STGMEDIUM ist com und damit CoTaskMemAlloc, die Zwischenablage Apis verschreiben GlobalAlloc()