使用SWIG代理C# - > C ++类包装器

时间:2014-04-17 11:12:06

标签: c# c++ proxy lambda swig

说我有以下C ++代码:

/* File : example.h*/
typedef void (__stdcall *CppCallback)(int code, const char* message);

class CppClass
{
public:
    CppClass() {};
    void call(CppCallback callback)
    {
        callback(1234, "Hello from C++");
    }
};

然后我有C#对应物:

/* File : example.cs */
using System;
using System.Text;

public delegate void CSharpCallback(int code, string param);

public class App
{
    static void Main()
    {
        CppClass cppClass = new CppClass();

        cppClass.call((i, s) => {
                Console.WriteLine("Code " + i + " and message '" + s + "'");
            });
    }
}

然后我将SWIG .i文件粘在一起:

/* File : example.i */
%module example

%include <windows.i>
%include <stl.i>

%{
#include "example.h"
%}

%define %cs_callback(TYPE, CSTYPE)
    %typemap(ctype) TYPE, TYPE& "void *"
    %typemap(in) TYPE  %{ $1 = ($1_type)$input; %}
    %typemap(in) TYPE& %{ $1 = ($1_type)&$input; %}
    %typemap(imtype, out="IntPtr") TYPE, TYPE& "CSTYPE"
    %typemap(cstype, out="IntPtr") TYPE, TYPE& "CSTYPE"
    %typemap(csin) TYPE, TYPE& "$csinput"
%enddef

%cs_callback(CppCallback, CSharpCallback)

%include "example.h"

现在,我想以这样的方式代理callback(),在执行C#lambda之前,它会做一些事情,比如print“Hooked”。为了使它成为可能,我还需要代理CppClass.call()方法,以便它将原始的回调/ lambda / delegate参数保存到call(),然后定义自己的处理程序(例如csharpCallback())并将其提供给P / Invoke对应于回调。当C ++应用程序调用callback()时,它将最终出现在我的C#csharpCallback()中,然后打印“Hooked”并调用C#cppClass.callback()中提供的原始保存回调。

问题 - 任何SWIG专家都可以提出一种优雅的解决方案来生成这种钩子包裹物吗?

1 个答案:

答案 0 :(得分:0)

首先应该决定如何在纯C#中实现这样的包装器。然后查看SWIG 2.0文档的19.8.7 Extending proxy classes with additional C# code部分。这可能有点棘手,因为你想包装委托,而不是类。看看你得到多远,并更新你的问题或发布答案!