假设我有以下 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() 方法,以便它将原始回调/lambda/委托(delegate)参数保存到 call(),然后定义自己的处理程序(例如 csharpCallback())并将其提供给 P/Invoke对应回调。当 C++ 应用程序调用 callback() 时,它将在我的 C# csharpCallback() 处结束,然后将打印“Hooked”并调用 C# cppClass.callback() 中提供的原始保存的回调。
问题 - 任何 SWIG 专家都可以提出一个优雅的解决方案来生成这种钩子(Hook)包装器吗?
最佳答案
您应该首先决定如何在纯 C# 中实现这样的包装器。然后看19.8.7 Extending proxy classes with additional C# code节SWIG 2.0 文档。这可能有点棘手,因为你想包装委托(delegate),而不是类。查看您的进展情况并更新您的问题或发布答案!
关于c# - 使用 SWIG 代理 C#->C++ 类包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23131583/