Преобразование делегата C++/CLI^ в длинное и обратно

Как я могу преобразовать PaintDelegate^ в long для отправки в качестве параметра refCon, чтобы, оказавшись внутри TrackTransferCB, я мог преобразовать его обратно и вызвать? Длинный, в который он преобразуется, ничего не значит, пока я могу преобразовать его обратно в делегат.

Это общая идея:

PaintDelegate^ paintDel = ...;
refCon = (long)paintDel;  // This conversion doesn't work

...

static OSErr TrackTransferCB(Track t, long refCon) {
    (PaintDelegate^)refCon->Invoke();  // This conversion doesn't work
}

Какие преобразования будут работать таким образом?


person jnm2    schedule 31.12.2010    source источник


Ответы (1)


Объекты-делегаты — это объекты со сборкой мусора, как и любой другой незначащий тип в .NET. Это означает, что сборщик мусора может их перемещать. Это означает, что получить их адрес не получится, адрес изменится, когда GC уплотнит кучу.

Я предполагаю, что вам нужно сделать это, чтобы передать неуправляемому коду какую-то ссылку на делегат. Ручка – типичное решение. Просто держите счетчик, который вы увеличиваете каждый раз, когда создаете новый объект. Сохраните его в Dictionary<int, PaintDelegate^>^ и передайте значение счетчика в неуправляемый код.

Marshal::GetFunctionPointerForDelegate() — это еще один подход, неуправляемый код теперь может напрямую вызывать цель делегата. Не долго, а пустота*. Однако вам все равно нужно хранить объект делегата в безопасном месте, чтобы он не собирал мусор. Я рекомендую первое.

person Hans Passant    schedule 31.12.2010
comment
На самом деле он работает в управляемом коде и вызывается из неуправляемого кода. Чтобы это работало, это статическая функция, поэтому я хочу вызвать нестатическую функцию, чтобы иметь доступ к частным нестатическим членам. Могу ли я закрепить местоположение делегата? - person jnm2; 31.12.2010
comment
Это то, что делает GetFunctionPointerForDelegate, он создает небольшой преобразователь для хранения ссылки на целевой экземпляр. Прикалывание не запрещено, но вы рискуете быть съеденными хищниками гото. - person Hans Passant; 31.12.2010
comment
Производительность имеет решающее значение для этой функции, поскольку она вызывается в реальном времени для каждого кадра видео. Может ли поиск в словаре быть достаточно быстрым? - person jnm2; 31.12.2010
comment
У вас не будет больше, сколько, 60 кадров в секунду? Держите руку на пульсе, за это время вы выполняете миллионы поисковых запросов в словаре. Не делайте этого для каждого пикселя. - person Hans Passant; 31.12.2010