Saltar al contenido

Cómo pasar un delegado o puntero de función de C# a C++ y llamarlo allí usando InternalCall

Puede que se de el caso de que halles algún error en tu código o proyecto, recuerda probar siempre en un ambiente de testing antes añadir el código al proyecto final.

Solución:

Después de algunas horas más de excavación, finalmente encontré una (¿la?) solución.
Básicamente, lo que funciona para el enfoque PInvoke también funciona aquí, puede pasar un puntero de función en lugar de un delegado de C# a C(++).
Preferiría una solución en la que pueda pasar un delegado directamente, pero siempre puede agregar un código contenedor en C# para que al menos se vea así.

Solución:

C#:

public delegate void CallbackDelegate(string message);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void setCallback(IntPtr aCallback);

private CallbackDelegate del; 
public void testCallbacks()

    System.Console.Write("Registering C# callback...n");
    del = new CallbackDelegate(callback01);
    setCallback(Marshal.GetFunctionPointerForDelegate(del));

    System.Console.Write("Calling passed C++ callback...n");


public void callback01(string message)

    System.Console.Write("callback 01 called. Message: " + message + "n");

C++:

typedef void (*CallbackFunction)(MonoString*);
void setCallback(CallbackFunction delegate)

    std::cout << &delegate << std::endl;
    delegate(mono_string_new(mono_domain_get(), "Test string set in C++"));

Sin embargo, tenga cuidado: debe mantener al delegado en C # de alguna manera (por eso lo asigné a "del") o será capturado por el GC y su devolución de llamada dejará de ser válida.
Tiene sentido, por supuesto, pero siento que esto es fácil de olvidar en este caso.

puede pasar el puntero de función como parámetro en c ++ a c # usando intptr_t.

MSDN no es preciso, el siguiente código funciona.

  // c++
  static void func(int param)
  
    //...
    

  void other_func()
  
    ptr->SetCallback( reinterpret_cast(func));
  

  // c#
  public static mydelegatetype somefunc = null;

  public void SetCallback(IntPtr function_pointer)
  
    somefunc = (mydelegatetype)
      Marshal.GetDelegateForFunctionPointer(function_pointer, typeof(mydelegatetype));
  

Te mostramos las reseñas y valoraciones de los usuarios

Puedes confirmar nuestra investigación añadiendo un comentario o dejando una puntuación te lo agradecemos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *