Estoy envolviendo una biblioteca C utilizando C++/CLI. La biblioteca C se diseñó para ser utilizada desde una clase C++ no administrada. Esto significa que las funciones de la biblioteca aceptan un puntero de objeto C++ y luego devuelven ese puntero a las devoluciones de llamada. Esto permite que el código de devolución de llamada redirija las solicitudes a una función de evento apropiada en el objeto C++ llamante.Contenedor de clase C++/CLI para biblioteca c - devoluciones de llamada
Las funciones reales son un poco complicado, así que han simplificado el espacio del problema a sólo unos pocos elementos básicos:
// 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)
{
}
}
Ahora las funciones de biblioteca C necesita ser llamado desde una clase administrada C++. En C++/CLI, el recolector de basura mueve objetos en la memoria, por lo que ya no funciona pasar un puntero fijo a la clase. Puedo resolver el problema fijando el objeto, pero no se recomienda porque conduce a la fragmentación de la memoria. Parece que otra opción sería usar punteros auto_gcroot, pero soy bastante nuevo en C++ administrado y no estoy seguro de cómo hacer que esto funcione.
¿Alguien sabe cómo hacer esto? ¿Qué tipo de puntero debería pasar a la función C? ¿Cómo debería la implementación de devolución de llamada redirigir a la función de evento del objeto llamante?
Esto solo es tangencialmente relevante para mi pregunta. Esto muestra cómo ajustar una clase de C++ no administrada dentro de una clase de C++ administrada y usar devoluciones de llamada. He encontrado muchos ejemplos de esto, incluidas muestras como http://tweakbits.com/UnmanagedToManagedCallback.cpp. Lo que estoy buscando es un ejemplo de cómo envolver una biblioteca C dentro de una clase C++/CLI y utilizar devoluciones de llamada. Al final del día, los problemas que estoy enfrentando son algo diferentes a los problemas resueltos en estas muestras. – Theo
Sí. Este ejemplo directo es tangencialmente relevante como es, pero se entendía como un puntero de dirección. Como no he hecho exactamente lo que me está preguntando, asumo que hacerlo es lo mismo que mi ejemplo. Aún crearías una clase bridge nativa y la incluirías en la clase administrada; luego, en lugar de pasar la clase al por mayor nativa (como en mi 'IProvider') podrías pasar una función estática de miembro que hace la llamada del objeto administrado. – CuppM
Agregué una versión de mi ejemplo usando su función C. – CuppM