Я оборачиваю библиотеку C, используя C ++ / CLI. Библиотека C была разработана для использования из неуправляемого класса C ++. Это означает, что библиотечные функции принимают указатель на объект C ++, а затем возвращают этот указатель в обратные вызовы. Это позволяет коду обратного вызова перенаправлять запросы к соответствующей функции события в вызывающем объекте C ++.
Фактические функции довольно задействованы, поэтому я упростил проблемное пространство до нескольких основных элементов:
// C library function signature
void CLibFunc(CLIBCALLBACK *callback, void *caller);
// C callback signature
// Second parameter is meant to point to the calling C++ object
typedef int (__stdcall CLIBCALLBACK) (int param1, void *caller);
// C callback implementation
int CallBackImpl(int param1, void* caller)
{
// Need to call the ManagedCaller's EventFunction from here
// ???
}
// C++/CLI caller class
public ref class ManagedCaller
{
public:
void CallerFunction(void)
{
// Call the C library function
// Need to pass some kind of this class pointer that refers to this object
CLibFunc(CallBackImpl, ????);
}
void EventFunction(param1)
{
}
}
Теперь библиотека C функции необходимо вызывать из управляемого класса C ++. В C ++ / CLI сборщик мусора перемещает объекты в памяти, поэтому передача простого фиксированного указателя на класс больше не работает. Я могу решить проблему, закрепив объект, но это не рекомендуется, поскольку это приводит к фрагментации памяти. Похоже, что еще один вариант - использовать указатели auto_gcroot, но я новичок в управляемом C ++ и не знаю, как это сделать.
Кто-нибудь знает, как это сделать? Какой указатель нужно передать функции C? Каким образом реализация обратного вызова должна перенаправлять на функцию события вызывающего объекта?