Я работаю с неуправляемой библиотекой 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
.