2008-12-26 14 views
14

Kiedy należy używać CoTaskMemAlloc? Czy ktoś może dać przykład?Korzystanie z CoTaskMemAlloc?

+0

Zamieszczam poniżej kilka informacji, kiedy może zajść potrzeba użycia CoTaskMemAlloc, ale może to być pomocne dla ciebie Jakiś kontekst dla twojego pytania ... – reuben

+0

Naprawiono pytanie i jego tytuł. – mmcdole

Odpowiedz

10

Gosh, musiałem myśleć chwilę temu - zrobiłem sporo programów COM na małą skalę z ATL i rzadko musiałem z nich korzystać.

Jest jedna sytuacja, która przychodzi do głowy: Windows Shell extensions. Jeśli masz do czynienia z zestawem obiektów systemu plików, możesz mieć do czynienia z PIDLs (wskaźnik do listy ID). Są to dziwne małe abstrakcje obiektów systemu plików i muszą być jawnie przydzielone/zwolnione przy użyciu przydziału przydzielania opartego na COM, takiego jak CoTaskMemAlloc. Istnieje również alternatywa, wskaźnik interfejsu IMalloc uzyskany z SHGetMalloc (przestarzały) lub CoGetMalloc - jest to po prostu warstwa abstrakcji do użycia, więc twój kod nie jest związany z konkretnym alokatorem pamięci i może użyć dowolnego odpowiedniego.

Punktem użyciu CoTaskMemAlloc lub IMalloc zamiast malloc() jest to, że alokacja pamięci/dealokacji musi być coś, co jest „COM-aware” tak, aby jego przydział i dealokacji są wykonywane konsekwentnie w czasie wykonywania, nawet jeśli alokacji i dealokacja jest wykonywana przez całkowicie niepowiązany kod (np. Windows przydziela pamięć, przesyła ją do twojego kodu C++, który później zwalnia, lub twój kod C++ przydziela, przesyła go do kodu VB innego użytkownika, który później zwalnia). Ani malloc() ani new nie są zdolne do współdziałania z stertą wykonawczą systemu, więc nie można ich użyć do alokacji pamięci w celu przesłania jej do innych obiektów COM lub do odbioru pamięci z innych obiektów COM i zwolnienia.

7

This MSDN article porównuje kilka różnych alokatorów narażonych przez Win32, w tym CoTaskMemAlloc. Jest używany głównie w programowaniu COM - szczególnie gdy wdrożenie serwera COM wymaga alokacji pamięci, aby powrócić do klienta. Jeśli nie piszesz serwera COM, prawdopodobnie nie musisz go używać.

(Jednakże, jeśli kod, który przydziela pamięć za pomocą CoTaskMemAlloc i odsyła go z powrotem do ciebie zadzwonić, będziesz musiał zwolnić zwrócony alokacji (s) przy użyciu CoTaskMemFree.)

+0

Dzięki Reuben, Moim żądaniem jest przydzielenie pamięci z procesora comserver w trakcie procesu -> zrobić ponowne wysłanie tego samego ze strony comclient, która jest znowu innym procesem, a następnie zwolnić go ze strony comserver ... Mam nadzieję, że mogę użyj cotaskmemxxx fns dla osiągnięcia tego samego - – atVelu

2

CoTaskMemAlloc jest taki sam jak malloc, z tym że poprzedni służy do alokacji pamięci używanej ponad granicami procesu.

tj. Jeśli mamy dwa procesy, proces1 i proces2, zakładamy, że proces1 jest serwerem COM, a proces2 jest klientem COM, który korzysta z interfejsów odsłoniętych przez proces1. Jeśli proces1 ma wysłać pewne dane, to może przydzielić pamięć za pomocą CoTaskMemAlloc, aby przydzielić pamięć i skopiować dane. Do tej lokalizacji pamięci można uzyskać dostęp przez proces2.

Biblioteka COM automatycznie wykonuje koordynizację i likwidację.

18

Użyj CoTaskMemAlloc podczas zwracania znaku * z natywnej biblioteki C++ do .NET jako ciąg.

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, trzeba przeznaczyć ciąg tak, nie można przeznaczyć go na stosie lub stercie używając malloc/nowy.

+0

Kiedy jest zwracany zasób zwracany przez 'Foo()'? Czy powinno to być zrobione ręcznie? –

+0

@ChieltenBrinke CLR będzie przestrzegać tych samych reguł GC dla zasobu, jak dla wszystkich innych zarządzanych zasobów. – zz3599

+0

@ zz3599 co to znaczy? CLR musi znać wszystkie odniesienia do tej pamięci. Ale w momencie wywoływania CoTaskMemAlloc nadal jesteśmy w niezarządzanym kodzie, tak daleko, jak CLR wie, że nie ma odniesień do tej pamięci. Oznaczałoby to jednak, że pamięć ta może zostać zebrana zaraz po przydzieleniu jej, co nie jest prawdą, ponieważ unieważnia ten przykład. Pytanie brzmi: jak to działa? –

3

tam naprawdę nie jest wiele, które można pomylić jako następujące połączenia wszystko skończyć z tym samym Przeznaczenie:

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

tylko jeśli używasz innych niż Windows (kompilator-Library) wywołuje jak malloc() wszystko pójdzie źle.

Oficjalnie należy stosować CoTaskMemAlloc dla COM nazywa (jak przydzielanie pole FORMATETC.ptd)

To CoTaskMemAlloc równa GlobalAlloc() pozostanie w ten sposób „do wieczności jest widoczne na api schowka kontra com STGMEDIUM. STGMEDIUM używa struktur i metod schowka, a STGMEDIUM to com, a co za tym idzie CoTaskMemAlloc, apis do schowka opisywał GlobalAlloc()