Использование CoTaskMemAlloc? - PullRequest
       9

Использование CoTaskMemAlloc?

14 голосов
/ 26 декабря 2008

Когда целесообразно использовать CoTaskMemAlloc? Может кто-нибудь привести пример?

Ответы [ 5 ]

19 голосов
/ 15 февраля 2011

Используйте CoTaskMemAlloc при возврате символа * из собственной библиотеки C ++ в .NET в виде строки.

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;
}

Так как .NET использует CoTaskMemFree , вы должны распределить строку следующим образом: вы не можете выделить ее в стеке или куче, используя malloc / new.

12 голосов
/ 26 декабря 2008

Черт возьми, мне пришлось немного подумать об этом - я выполнил немало мелкого COM-программирования с ATL и редко использовал его.

Однако на ум приходит одна ситуация: Расширения оболочки Windows . Если вы имеете дело с набором объектов файловой системы, вам, возможно, придется иметь дело с PIDLs (указатель на список идентификаторов). Это причудливые небольшие абстракции объектов файловой системы, и они должны быть явно выделены / освобождены с использованием распределителя с поддержкой COM, такого как CoTaskMemAlloc. Существует также альтернатива, указатель интерфейса IMalloc, полученный из SHGetMalloc (устарело) или CoGetMalloc - это просто уровень абстракции для использования, так что ваш код не привязан к конкретный распределитель памяти и может использовать любой подходящий.

Смысл использования CoTaskMemAlloc или IMalloc вместо malloc() заключается в том, что выделение / освобождение памяти должно быть чем-то, что "COM-осознает", чтобы его распределение и освобождение выполнялись согласованно во время выполнения даже если выделение и освобождение выполняются с помощью совершенно не связанного кода (например, Windows выделяет память, передает ее в ваш код C ++, который впоследствии освобождается, или ваш код C ++ выделяет, передает его в чужой код VB, который позднее освобождает). Ни malloc(), ни new не способны взаимодействовать с динамической кучей системы, поэтому их нельзя использовать для выделения памяти для передачи другим объектам COM или для получения памяти от других объектов COM и освобождения.

7 голосов
/ 26 декабря 2008

В этой статье MSDN сравниваются некоторые из различных распределителей, предоставляемых Win32, включая CoTaskMemAlloc. Он в основном используется в программировании COM - особенно, когда реализация COM-сервера должна выделить память для возврата клиенту. Если вы не пишете COM-сервер, вам, вероятно, не нужно его использовать.

(Однако, если вы вызываете код, который выделяет память с помощью CoTaskMemAlloc и возвращает его вам, вам необходимо освободить возвращенные выделения, используя CoTaskMemFree .)

3 голосов
/ 21 июня 2011

на самом деле мало что может пойти не так, поскольку все следующие вызовы заканчиваются одинаковым распределением:

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

только если вы используете вызовы не-windows (библиотека-компилятор), такие как malloc(), все пойдет не так.

Официально следует использовать CoTaskMemAlloc для COM-вызовов (например, выделение поля FORMATETC.ptd)

То, что CoTaskMemAlloc равно GlobalAlloc(), останется таким "до тех пор, пока в буфере обмена api против com STGMEDIUM не будет видна вечность". STGMEDIUM использует структуры и метод буфера обмена, и пока STGMEDIUM com и, следовательно, CoTaskMemAlloc, apis буфера обмена предписывает GlobalAlloc()

2 голосов
/ 29 декабря 2008

CoTaskMemAlloc такой же, как malloc, за исключением того, что прежний используется для выделения памяти, которая используется через границы процесса.

Т.е., если у нас есть два процесса, process1 и process2, предположим, что process1 - это COM-сервер, а process2 - это COM-клиент, который использует интерфейсы, предоставляемые process1. Если process1 должен отправить некоторые данные, он может выделить память, используя CoTaskMemAlloc, чтобы выделить память и скопировать данные. Эта ячейка памяти доступна для process2.

Библиотека COM автоматически выполняет маршалинг и демаршаллинг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...