So I have next C++ code:
#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;
};
}
And .i file:
/* 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";
I created being inspired by this thread. Code gets generated.
Yet I can not understand how to get code like
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; }
};
}
}
}
compile. 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
WhereSWIGTYPE_p_f_r_q_const__std__vector__double___double__void
looks like this:
/* ----------------------------------------------------------------------------
* 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;
}
}
}
So I wonder what shall be changed in .i
file or added to c# generated wrapper to get the ability to pass my C# lambda to C++ class as delegate?
To create a file in a 'C' program following syntax is used, FILE *fp; fp = fopen ("file_name", "mode"); In the above syntax, the file is a data structure which is defined in the standard library. fopen is a standard function which is used to open a file.
The read() function reads data previously written to a file. If any portion of a regular file prior to the end-of-file has not been written, read() shall return bytes with value 0. For example, lseek() allows the file offset to be set beyond the end of existing data in the file.
The write() function shall attempt to write nbyte bytes from the buffer pointed to by buf to the file associated with the open file descriptor, fildes.
r+ - opens a file in both read and write mode.
Got this working for following configuration:
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);
Corresponding .i file for this is:
/* 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"
NOTE: I've tried with non-constant reference to state-type, but with constant reference shall work also.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With