Закрепление экземпляра класса с помощью GCHandle.Alloc в C # - PullRequest
0 голосов
/ 07 января 2019

Я работаю с неуправляемой библиотекой C, которая имеет функцию обратного вызова, которая вызывается из внутреннего потока в библиотеке C. Обратный вызов имеет параметр void * 'context'.

Я хочу установить в этом контексте адрес экземпляра класса C #, чтобы я мог получить доступ к полям и свойствам членов из обратного вызова.

Насколько я понимаю, мне нужно закрепить память класса, чтобы убедиться, что GC не перемещает его, так как код C будет принимать копию адреса экземпляра. Тем не менее, GCHandle.Alloc () утверждает, что: «Экземпляр с непримитивными (не blittable) членами не может быть закреплен».

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

Как я могу передать адрес экземпляра класса C # в мой код C ++ и убедиться, что адрес остается действительным (т.е. GC не перемещается)?

РЕДАКТИРОВАТЬ # 1 Исправление: библиотека является библиотекой C, а не C ++, как указано ранее (исправлено в тексте выше). Не то чтобы это имело какое-либо значение.

Это прототип для обратного вызова C:

void Callback(uint32_t hCamera, uint32_t dwInterruptMask, void *pvParams);

И завернутый в C #:

[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public unsafe delegate void PHX_AcquireCallBack(uint hCamera, uint dwInterruptMask, 
    IntPtr pvParams);

pvParams передается в библиотеку C при установке обратного вызова. Библиотека хранит указатель, но никак не пытается получить к нему доступ. Он просто передает его обратно всякий раз, когда вызывает обратный вызов.

При использовании библиотеки из кода C ++ я обычно передаю указатель this для pvParams.

...