我如何获得SWIG来自动包装模拟的"this"?指向C结构的指针? [英] How do I get SWIG to automatically wrap an emulated "this" pointer to a C struct?

查看:92
本文介绍了我如何获得SWIG来自动包装模拟的"this"?指向C结构的指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了一个简单的C类",它使用结构体中的函数指针来实现成员函数,并将指向该结构体的指针作为每个函数的第一个参数传递,类似于隐式的"this" "C ++中的指针.

I've got a simple C "class" I have implemented, using function pointers in a struct to implement the member functions, and passing a pointer to the struct as the first argument to each function, similar to the implicit "this" pointer in C++.

%module mytest
%{
typedef struct mytest mytest;

struct mytest {
  int data;
  int (*func1)(mytest *,int);
  void (*func2)(mytest *,int);
};

int f1(mytest *me,int n) { return me->data + n; }
void f2(mytest *me,int n) { me->data += n; }

mytest *mytestNew(int n) {
  mytest *me = (mytest*) malloc(sizeof(mytest));
  me->data = n;
  me->func1 = f1;
  me->func2 = f2;
  return me;
}

%}

typedef struct mytest mytest;

struct mytest {
  int data;
  int func1(mytest *,int);
  void func2(mytest *,int);
};

extern mytest *mytestNew(int n);

现在,我的问题是,当使用我在前端选择的任何语言创建接口时,即使该语言本身支持隐藏它,我最终也必须显式地将"this"指针传递给该对象.

Now my problem is, when the interface is created to whatever language I choose in the front end, I wind up having to explicitly pass the "this" pointer to the object, even though the language itself supports hiding this.

例如,假设我选择了Python.我必须做这样的事情:

For instance, suppose I choose Python. I have to do something like this:

from mytest import *
m = mytestNew(1)
m.func1(m,0)

我真正想要的是这样做:

Where what I really want is to do it like this:

from mytest import *
m = mytestNew(1)
m.func1(0)

我知道我可以编写一些包装代码,但是对于我的实际项目,我在很多现有C代码的对象中都有很多功能,并将其乘以我要支持的每种语言,这也是很多工作!有什么方法可以让SWIG自动执行此操作?

I know I could just write some wrapping code, but for my actual project I have a lot of functions in a lot of objects of existing C code, and multiplying this by every language that I want to support, this is just too much work! Is there some way to get SWIG to do this automatically?

推荐答案

您可以在SWIG中以语言中立的方式执行此操作,只需两个类型映射即可,只要您在SWIG接口中命名参数并使其一致即可要有选择地应用的类型图. (除非您当然希望所有指向mytest的指针在默认情况下都成为"this"指针)

You can do this in a language neutral way in SWIG with just two typemaps provided you name the parameter something consistent in the SWIG interface as well as the definitions to allow the typemaps to be applied selectively. (Unless you wanted all pointers to mytest to become "this" pointers by default of course)

您需要的类型图是:

// 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;
}

check typemap并非真正打算用于这种用途,但这是在从目标语言中提取参数之后以及进行实际调用之前获取注入代码的最简单方法.

The check typemap isn't really intended for use like this, but it's the easiest way to get the code to be injected after the arguments have been extracted from the target language and before the actual call is made.

您还可以在宏的帮助下简化模块,以避免必须编写并保持功能指针与成员技巧之间的映射保持同步.我最终以test.h作为

You can also simplify the module with the help of a macro to avoid having to write and keep in sync the mapping between the function pointers and the members trick. I ended up with 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):

And the corresponding interface file (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并在后台设置函数指针)

(This interface file provides a constructor that "creates" the "object" exactly how a Java programmer would expect - you can call new and it sets the function pointers behind the scenes)

这篇关于我如何获得SWIG来自动包装模拟的"this"?指向C结构的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆