How do I get SWIG to automatically wrap an emulated “this” pointer to a C struct?

我是研究僧i 提交于 2019-11-29 10:53:55

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)

The typemaps you need are:

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

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.

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

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"

(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)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!