programas - llamando a funciones de C++ que contienen devoluciones de llamada en C#
funciones en c++ pdf (3)
Todo lo que necesita hacer es crear la función ac # que coincida con la firma del delegado que declaró. Cree un delegado, retenga una referencia a este delegado para que no se recoja basura, y llame a la importación dll con el delegado como devolución de llamada.
entonces tendrías algo como esto:
public void MyCallback(IntPtr P)
{
//do something
}
// somewhere else in your code
var cb = new CallbackFunc(MyCallback);
CodecStart(..., cb, ...);
Hola, estoy tratando de entender esto llamando a esta función c ++ en c #:
BOOL __stdcall CodecStart(int hRadio,void __stdcall (*CallbackFunc)(void *),void *CallbackTarget);
esto es de una api de WinRadio que se encuentra aquí http://www.winradio.com/home/g305_sdk.htm .
Encontré que otras personas preguntaban acerca de llamar a esta función específica en la red y tenían:
public delegate void CallbackFunc( IntPtr p);
[DllImport("WRG305API.dll")]
public static extern bool CodecStart(int hRadio, CallbackFunc func, IntPtr CallbackTarget);
pero no puedo entender cómo implementar esto más.
cualquier pensamiento u orientación sobre cómo llamar esto?
muchas gracias
Una función de devolución de llamada es un código que llama un dll (que está importando en este caso) que realiza algunas funciones. También necesita aprender a trabajar con los delegados en c # . Puede implementar el código de esta manera:
public void MyCallback(IntPtr p)
{
//do something
}
y luego tu llamada a dll será así:
[DllImport("WRG305API.dll")]
public static extern bool CodecStart(int hRadio, func, IntPtr CallbackTarget);
Si necesita más orientación, publique la versión en C ++ del código que desea convertir y podemos ayudarlo con la versión de C #.
Aquí hay una implementación simple que lo pondrá todo junto.
class WinRadioWrapper
{
public delegate void CallbackFunc( IntPtr pData );
[DllImport( "WRG305API.dll" )]
public static extern bool CodecStart( int hRadio, CallbackFunc func, IntPtr CallbackTarget );
public bool CodecStartTest(int hRadio)
{
bool bStarted = CodecStart( hRadio, MyCallbackFunc, IntPtr.Zero );
return bStarted;
}
// Note: this method will be called from a different thread!
static void MyCallbackFunc( IntPtr pData )
{
// Sophisticated work goes here...
}
}
Tenga en cuenta que debido a que
MyCallbackFunc
se ejecutará en un hilo diferente, elegí hacerstatic
. De esta forma, no tendrá la tentación de acceder a los miembros de datos deWinRadioWrapper
.Para simplificar, pasé un parámetro
IntPtr.Zero
a la devolución de llamada, pero esto puede apuntar a cualquier información que desee utilizar en la devolución de llamada.
[Por favor, ignore este párrafo] Mire enMarshal.StructureToPtr
si desea pasar datos a la devolución de llamada, pero asegúrese de anclar también los datos que está pasando para asegurarse de que no se recogen basura (consulteGCHandle
para más detalles).
EDITAR:
Con las palabras interesantes de svick (¡gracias!), Me doy cuenta de que estaba mezclando un objeto copiado con uno fijo.
Entonces, para resolver las cosas:
-
Marshal.StructureToPtr
debe usar si desea copiar una estructura de datos existente y luego pasarla a la función de devolución de llamada. - Si, por otro lado, desea utilizar y la estructura de datos existente (por ejemplo, para modificar su contenido), debe usar
GCHandle
para fijarlo en la memoria y evitar que se recolecte basura.
Esto, sin embargo, agregará algunos gastos generales de mantenimiento para elGCHandle
.