tipos tipo puede programacion indicado funcion expresiones expresion eventos ejemplos delegados delegado convertir caracteristicas anonima c# c++ .net windows swig

tipo - ¿Cómo crear un pasable de C#a un delegado de C++ que tome un IEnumerable como argumento con SWIG?



programacion de eventos c# (1)

Consiguió este trabajo para la siguiente configuración:

public class StateTypeCustomMarshaller : ICustomMarshaler { public static ICustomMarshaler GetInstance(string s) { return new StateTypeCustomMarshaller(); } public object MarshalNativeToManaged(IntPtr pNativeData) { return new state_type(pNativeData, false); } public IntPtr MarshalManagedToNative(object ManagedObj) { throw new NotImplementedException(); } public void CleanUpNativeData(IntPtr pNativeData) { throw new NotImplementedException(); } public void CleanUpManagedData(object ManagedObj) { } public int GetNativeDataSize() { throw new NotImplementedException(); } } public delegate void ObserverDelegate( [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(StateTypeCustomMarshaller))]state_type state, double d);

El archivo .i correspondiente para esto es:

/* File : MyProject.i */ %module MyProject %include "std_vector.i" %template(state_type) std::vector<double>; //// Delegate realated stuff //// %typemap(csin) void (*)(OdeProxy::state_type&, double) "$csinput"; %typemap(cstype) void (*)(OdeProxy::state_type&,double) "ConsoleApplication2.Helpers.ObserverDelegate"; %typemap(imtype) void (*)(OdeProxy::state_type&, double) "ConsoleApplication2.Helpers.ObserverDelegate"; %typemap(csvarout) void (*)(OdeProxy::state_type&, double) %{ get { return $imcall; } %} %{ #include "OdeProxy.h" %} %include "OdeProxy.h"

NOTA: He intentado con una referencia no constante al tipo de estado, pero con una referencia constante también funcionará.

Así que tengo el siguiente código de C ++:

#ifdef WIN32 # undef CALLBACK # define CALLBACK __stdcall #else # define CALLBACK #endif #include <iostream> #include <vector> namespace OdeProxy { typedef std::vector< double > state_type; typedef void (CALLBACK *System)( const state_type &, state_type &, const double); typedef void (CALLBACK *Observer)( const state_type &, double); class Ode { public: state_type initialConditions; System system; Observer observer; double from; double to; double step; }; }

Y el archivo .i:

/* File : MyProject.i */ %module MyProject %{ #include "C++/OdeProxy.h" %} %include "std_vector.i" %include "C++/OdeProxy.h" %template(state_type) std::vector<double>; //// Delegate realated stuff //// %typemap(cstype) void (*)( const state_type &, state_type &, const double) "SystemDelegate"; %typemap(imtype) void (*)( const state_type &, state_type &, const double) "SystemDelegate"; %typemap(cstype) void (*)( const state_type &, double) "ObserverDelegate"; %typemap(imtype) void (*)( const state_type &, double) "ObserverDelegate";

Creé inspirándome en este thread . El código se genera.

Sin embargo, no puedo entender cómo obtener código como

using OdeLibrary; namespace OdeTest { class Program { static void Main(string[] args) { //var lam = new OdeLibrary.SWIGTYPE_p_f_r_q_const__std__vector__double___double__void() var ode = new Ode{ from = 0, to = 10, initialConditions = new state_type(new[]{1,2,3}), step = 0.01, observer = (x, dxdt, t) => { return; } }; } } }

compilar. Error:

Error Cannot convert lambda expression to type ''OdeLibrary.SWIGTYPE_p_f_r_q_const__std__vector__double___double__void'' because it is not a delegate type

Donde SWIGTYPE_p_f_r_q_const__std__vector__double___double__void tiene este aspecto:

/* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). * Version 2.0.9 * * Do not make changes to this file unless you know what you are doing--modify * the SWIG interface file instead. * ----------------------------------------------------------------------------- */ namespace OdeLibrary { using System; using System.Runtime.InteropServices; public class SWIGTYPE_p_f_r_q_const__std__vector__double___double__void { private HandleRef swigCPtr; internal SWIGTYPE_p_f_r_q_const__std__vector__double___double__void(IntPtr cPtr, bool futureUse) { swigCPtr = new HandleRef(this, cPtr); } protected SWIGTYPE_p_f_r_q_const__std__vector__double___double__void() { swigCPtr = new HandleRef(null, IntPtr.Zero); } internal static HandleRef getCPtr(SWIGTYPE_p_f_r_q_const__std__vector__double___double__void obj) { return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; } } }

Así que me pregunto qué se cambiará en el archivo .i o se agregará al envoltorio generado por c # para obtener la capacidad de pasar mi C # lambda a la clase de C ++ como delegado.