SWIG Importing generated class from a different module and package into the current class

懵懂的女人 提交于 2019-12-06 05:35:04

问题


I'm having difficulty getting the SWIG typemap(javapackage) to work properly. I tried making a simple version of the problem, and even that seems to fail.

foo.h:

#ifndef FOO_H
#define FOO_H

class Foo
{
public:
    Foo() {};
    int doSomething() { return 1 };
};

#endif

bar.h:

#ifndef BAR_H
#define BAR_H

#include "foo.h"

class Bar
{
public:
    Bar() {};
    int doSomething(Foo foo) { return foo.doSomething(); };
};

#endif

Foo.i

%module FooMod

%include "typemaps.i"
%include "stdint.i"

%{
#include "../header/foo.h"
%}

%include "../header/foo.h"

Bar.i

%module BarMod

%import "Foo.i"

%typemap("javapackage") Foo, Foo *, Foo & "com.me.t.foo";

%include "typemaps.i"
%include "stdint.i"

%{
#include "../header/bar.h"
%}

%include "../header/bar.h"

Running these with this the following commands:

swig -c++ -java -package com.me.t.foo -outdir ../../src/com/me/t/foo -o ../src/Foo.cpp Foo.i
swig -c++ -java -package com.me.t.bar -outdir ../../src/com/me/t/bar -o ../src/Bar.cpp Bar.i

And I get this output:

package com.me.t.bar;

public class Bar {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  protected Bar(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  protected static long getCPtr(Bar obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        BarModJNI.delete_Bar(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public Bar() {
    this(BarModJNI.new_Bar(), true);
  }

  public int doSomething(Foo foo) {
    return BarModJNI.Bar_doSomething(swigCPtr, this, Foo.getCPtr(foo), foo);
  }

}

BarModJNI.java:

package com.me.t.bar;

public class BarModJNI {
  public final static native long new_Bar();
  public final static native int Bar_doSomething(long jarg1, Bar jarg1_, long jarg2, Foo jarg2_);
  public final static native long Bar_getFoo(long jarg1, Bar jarg1_);
  public final static native void delete_Bar(long jarg1);
}

The files are generated properly, but notice that there is no import statement, so Foo can't be found from either of the Bar Java classes. This is a simple example, but just hard-coding an import statement isn't an option for me since the generated source files containing the C JNI code might have the wrong locations of the "Foo" class files.

This seems like a very simple and common problem, so, what I'm wondering is if I'm missing something or if I'm doing something wrong.

Thanks for the help!


回答1:


Got the same problem and found answer, so posting it for community.

You need to make 3 changes.

  1. Add import statements to generated proxy class (Bar.java):

    // Bar.i
    %pragma(java) jniclassimports=%{
    import com.me.t.foo.Foo;
    %}
    
  2. Add import statements to generated JNI wrapper class (BarModJNI.java):

    // Bar.i
    %typemap(javaimports) Bar %{
    import com.me.t.foo.Foo;
    %}
    
  3. Tell SWIG to make Foo.getCPtr a public member variable because Bar class will want to access it:

    // Foo.i
    SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
    SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
    

Reference:

  • http://www.swig.org/Doc2.0/SWIGDocumentation.html#Java_code_typemaps
  • http://www.swig.org/Doc2.0/SWIGDocumentation.html#Java_imclass_pragmas



回答2:


Just a couple of comments on the answer provided by Zbigniew. I have faced the same problem described in this post. I would like to clarify two points.

Firstly, it seems to me that step 1 is for adding the import in JNI wrapper class (whateverJNI.java) while step 2 is for adding import to the specific class.

Secondly, step 2 is not working for me, instead of %typemap(javaimports) <class> I had to use %typemap(javaimports) SWIGTYPE. Bad thing is it adds the imports to all the generated java classes and not only to the desired one.

Finally, I am still having the problem that SWIG does not recognize the imported class when wrapping the specific type and it still uses SWIGTYPE_<type> instead of directly <type>



来源:https://stackoverflow.com/questions/16499202/swig-importing-generated-class-from-a-different-module-and-package-into-the-curr

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