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

本文关键字:C++ 包装 SWIG 使用 C#- gt 代理 | 更新日期: 2023-09-27 17:58:49

假设我有以下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之前,它会做一些事情,比如打印"Hooked"。为了实现这一点,我还需要代理CppClass.call()方法,这样它就可以将原始的callback/lambda/delegate参数保存到call()中,然后定义自己的处理程序(例如csharpCallback()),并将其提供给回调对应的P/Invoke。当C++应用程序调用callback()时,它将终止于我的C#csharpCallback(),然后它将打印"Hooked"并调用原始保存的回调,该回调在C#cppClass.callback()中提供。

问题是,任何SWIG专家都能为生成这种钩子包装器提出一个优雅的解决方案吗?

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

您应该首先决定如何在纯C#中实现这样的包装器。然后看第19.8.7节使用SWIG2.0文档的附加C#代码扩展代理类。这可能有点棘手,因为您想要包装委托,而不是类。看看你能走多远,更新你的问题或发布答案!