添加具有本机Java类型参数的接口

时间:2013-08-04 15:50:19

标签: awt swig

我想使用swig创建一个JNI接口,而不是以C ++函数存在的常用方式。我想添加一个带有java类参数的方法/函数。

档案:test.i

%typemap(javaimports) A %{
import java.awt.Component;
%}

%extend(java) A {
  void Attach( Component awt)
  {
    // here I Want to retrieve XDisplay, Window, Screen from 
    // /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.25.x86_64/include/jawt.h
    // I need canvas of type jobject.
    // with this information I call Attach( XDisplay * dpy, Window win);
  }
}

class A
{
public:
   void Attach( XDisplay * dpy, Window win);
};

1 个答案:

答案 0 :(得分:0)

您需要一些类型地图才能将java.awt.Component作为jobject传递给扩展方法:

%module test

%typemap(jstype) jobject *awtcomponent "java.awt.Component";
%typemap(jtype) jobject *awtcomponent "java.awt.Component";
%typemap(jni) jobject *awtcomponent "jobject";
%typemap(javain) jobject *awtcomponent "$javainput";

%extend A {
  void attach(jobject awtcomponent) {
    // Call whatever JNI functions you want with this jobject 
    // (which is always an AWT component)

    // Then:
    $self->Attach(arg1, arg2);
  }
}

%inline %{
struct A {
};
%}

鉴于您已经拥有成员函数,您实际上可以完全跳过%extend并使用类型映射来直接处理:

%module test
%typemap(jstype) (XDisplay * dpy, Window win)  "java.awt.Component";
%typemap(jtype) (XDisplay * dpy, Window win) "java.awt.Component";
%typemap(jni) (XDisplay * dpy, Window win) "jobject";
%typemap(javain) (XDisplay * dpy, Window win)  "$javainput";

%typemap(in,numinputs=1) (XDisplay * dpy, Window win) {
  // some JNI to convert $input (jobject) into $1 (dpy) and $2 (win)
}

%inline %{
struct A {
  void Attach(XDisplay * dpy, Window win) {}
};
%}

这些类型地图还有一个额外的好处,即无需额外工作就可以在XDisplayWindow配对的任何地方工作。

从jawt.h示例派生的完整示例,所有JNI填写完成:

%module test

%{
#include <X11/Xlib.h>
#include <jawt.h>
#include <jawt_md.h>
#include <cassert>
%}

%typemap(jstype) (Display * dpy, Window win)  "java.awt.Component";
%typemap(jtype) (Display * dpy, Window win) "java.awt.Component";
%typemap(jni) (Display * dpy, Window win) "jobject";
%typemap(javain) (Display * dpy, Window win)  "$javainput";

%typemap(in,noblock=1,numinputs=1) (Display * dpy, Window win) {
  // some JNI to convert $input (jobject) into $1 (dpy) and $2 (win)
  JAWT awt;
  JAWT_DrawingSurface* ds;
  JAWT_DrawingSurfaceInfo *dsi;
  JAWT_X11DrawingSurfaceInfo* dsi_x11;
  jboolean result;
  jint lock;

  awt.version = JAWT_VERSION_1_3;
  result = JAWT_GetAWT(jenv, &awt);
  assert(result != JNI_FALSE);

  ds = awt.GetDrawingSurface(jenv, $input);
  assert(ds != NULL);

  lock = ds->Lock(ds);
  assert((lock & JAWT_LOCK_ERROR) == 0);

  dsi = ds->GetDrawingSurfaceInfo(ds);
  dsi_x11 = (JAWT_X11DrawingSurfaceInfo*)dsi->platformInfo;
  $1 = dsi_x11->display;
  $2 = dsi_x11->drawable;
}

%typemap(freearg) (Display * dpy, Window win) {
  ds->FreeDrawingSurfaceInfo(dsi);
  ds->Unlock(ds);
  awt.FreeDrawingSurface(ds);
}

%inline %{
struct A {
  void Attach(Display * dpy, Window win) {}
};
%}

两个值得注意的变化是添加的freearg类型映射,它在调用cleanup之后运行,而noblock=1则使本地临时变量对freearg可见。