您可以在 SWIG 中以语言中立的方式执行此操作,只需使用两个类型映射,前提是您将参数命名为与 SWIG 接口中一致的名称以及允许有选择地应用类型映射的定义。 (除非你想要所有的指针mytest
当然默认成为“this”指针)
您需要的类型映射是:
// Make sure the wraqpped function doesn't expect an input for this:
%typemap(in,numinputs=0) mytest *me "$1=NULL;"
// Slightly abuse check typemap, but it needs to happen after the rest of the arguments have been set:
%typemap(check) mytest *me {
$1 = arg1;
}
检查类型映射并不是真正适合这样使用的,但它是在从目标语言中提取参数之后和进行实际调用之前注入代码的最简单方法。
您还可以借助宏来简化模块,以避免编写函数指针和成员技巧之间的映射并保持同步。我最终得到test.h
as:
#ifdef SWIG
#define MEMBER(name, args) name args
#else
#define MEMBER(name, args) (*name) args
#endif
typedef struct mytest mytest;
struct mytest {
int data;
int MEMBER(func1,(mytest *me,int));
void MEMBER(func2,(mytest *me,int));
};
以及对应的接口文件(test.i):
%module test
%{
#include "test.h"
static int f1(mytest *me,int n) { return me->data + n; }
static void f2(mytest *me,int n) { me->data += n; }
%}
%extend mytest {
mytest(int n) {
$self->data = n;
$self->func1 = f1;
$self->func2 = f2;
}
}
%typemap(in,numinputs=0) mytest *me "$1=NULL;"
%typemap(check) mytest *me {
$1 = arg1;
}
%include "test.h"
(这个接口文件提供了一个构造函数,它完全按照 Java 程序员的期望“创建”“对象”——您可以调用new
它在幕后设置函数指针)