我很难让SWIG typemap(javapackage)正常工作。我尝试制作一个问题的简单版本,即使这似乎也失败了。
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"
使用以下命令运行这些命令:
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
我得到了这个输出:
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);
}
文件生成正确,但请注意无导入语句,因此无法从任何一个Bar Java类中找到 Foo 。这是一个简单的例子,但只是硬编码import语句对我来说不是一个选项,因为生成的包含C JNI代码的源文件可能具有“Foo”类文件的错误位置。
这似乎是一个非常简单和常见的问题,所以,我想知道的是,如果我错过了什么或者我做错了什么。
感谢您的帮助!
答案 0 :(得分:4)
遇到同样的问题并找到答案,所以将其发布给社区。 p>
您需要进行3次更改。
将import语句添加到生成的代理类(Bar.java):
// Bar.i
%pragma(java) jniclassimports=%{
import com.me.t.foo.Foo;
%}
将import语句添加到生成的JNI包装类(BarModJNI.java)中:
// Bar.i
%typemap(javaimports) Bar %{
import com.me.t.foo.Foo;
%}
告诉SWIG使Foo.getCPtr
成为公共成员变量,因为Bar类需要访问它:
// Foo.i
SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
参考:
答案 1 :(得分:0)
Zbigniew提供的答案只有几点评论。我遇到过这篇文章中描述的同样问题。我想澄清两点。
首先,在我看来,第1步是在JNI包装类(whateverJNI.java)中添加导入,而第2步是在特定类中添加导入。
其次,第2步对我不起作用,而不是%typemap(javaimports) <class>
我必须使用%typemap(javaimports) SWIGTYPE
。糟糕的是它将导入添加到所有生成的java类,而不仅仅是所需的类。
最后,我仍然遇到SWIG在包装特定类型时无法识别导入的类的问题,它仍然使用SWIGTYPE_<type>
而不是直接使用<type>
答案 2 :(得分:0)
我也遇到过同样的问题。 我通过写解决了(您需要在.i文件中写)
%typemap(javaimports) namespace::classname
%{
import com.yourcompany.yourapp.*;
%}
此代码仅生成您指定的类的import语句。
注意:必须指定本机名称空间,否则将看不到您的类!
示例: 如果您的C ++代码是这样的:
namespace A{
class MyPerfectClass{
};
}
您需要写
%typemap(javaimports) A::MyPerfectClass
%{
import com.yourcompany.yourapp.*;
%}
如果要将此import语句添加到所有Java包装的类中,则需要编写
%typemap(javaimports) SWIGTYPE
%{
import com.yourcompany.yourapp.*;
%}
对于JNI Java类:
%pragma(java) jniclassimports=%{
import com.yourcompany.yourapp.*;
%}
证明代码在这里:
package com.mycompany.myproject.A_package;
import com.mycompany.myproject.B_package.*;
public class MYCLASS{
private transient long swigCPtr;
protected transient boolean swigCMemOwn;
public MYCLASS(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
public static long getCPtr(MYCLASSobj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
.
. etc.
如果您有多个班级,则可以继续:
%typemap(javaimports) A::MyPerfectClass , A::B::MyFantasticClass , MyNoNamespaceClass
我已经使用SWIG 4.0进行了测试,并且可以使用。
我已更改证明代码上的包裹和类别名称,因为我无法共享我的公司和类别名称。我希望这个答案对遇到同样问题的其他人有所帮助。