说我有以下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专家都可以提出一种优雅的解决方案来生成这种钩子包裹物吗?
答案 0 :(得分:0)
首先应该决定如何在纯C#中实现这样的包装器。然后查看SWIG 2.0文档的19.8.7 Extending proxy classes with additional C# code部分。这可能有点棘手,因为你想包装委托,而不是类。看看你得到多远,并更新你的问题或发布答案!