gpt4 book ai didi

c# - 如何使用 SWIG 将 IEnumerable 作为参数的 C++ 委托(delegate)从 C# 创建传递?

转载 作者:IT老高 更新时间:2023-10-28 22:15:22 38 4
gpt4 key购买 nike

所以我有下一个 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;
};
}

还有.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";

我的创作灵感来自 thread .生成代码。

但我不明白如何获取类似的代码

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; }
};
}
}
}

编译。错误:

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

其中SWIGTYPE_p_f_r_q_const__std__vector__double___double__void 看起来像这样:

/* ----------------------------------------------------------------------------
* 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;
}
}

}

所以我想知道应该在 .i 文件中进行哪些更改或添加到 c# 生成的包装器中以获得将我的 C# lambda 作为委托(delegate)传递给 C++ 类的能力?

最佳答案

让这个工作适用于以下配置:

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);

对应的.i文件是:

/* 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"

注意:我尝试过使用非常量引用状态类型,但使用常量引用也可以。

关于c# - 如何使用 SWIG 将 IEnumerable 作为参数的 C++ 委托(delegate)从 C# 创建传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16659981/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com