将从不同模块和包生成的类导入到当前类中
SWIG Importing generated class from a different module and package into the current class
我很难让SWIG typemap(javpackage)正常工作。我试着做一个简单的版本的问题,甚至似乎失败了。
foo:
#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);
}
文件被正确地生成,但是注意没有import语句,所以Foo不能从两个Bar Java类中找到。这是一个简单的例子,但是仅仅硬编码一个import语句对我来说不是一个选择,因为生成的包含C JNI代码的源文件可能有错误的"Foo"类文件的位置。
这似乎是一个非常简单和常见的问题,所以,我想知道的是,如果我错过了什么,或者如果我做错了什么。
谢谢你的帮助!
我也遇到了同样的问题,也找到了答案,所以把它贴在了社区里。
你需要做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)
- http://www.swig.org/Doc2.0/SWIGDocumentation.html Java_code_typemaps
- http://www.swig.org/Doc2.0/SWIGDocumentation.html Java_imclass_pragmas
对Zbigniew提供的答案有几点评论。我遇到过这篇文章中描述的同样的问题。我想澄清两点。
首先,在我看来,第1步是在JNI包装器类(whateverJNI.java)中添加导入,而第2步是在特定类中添加导入。
其次,步骤2不适合我,而不是%typemap(javaimports) <class>
,我不得不使用%typemap(javaimports) SWIGTYPE
。糟糕的是,它将导入添加到所有生成的java类中,而不仅仅是添加到所需的java类中。
最后,我仍然有SWIG在包装特定类型时不识别导入类的问题,它仍然使用SWIGTYPE_<type>
而不是直接使用<type>
我也遇到过同样的问题。我通过写(你需要写在。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.*;
%}
For JNI Java Class:
%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测试过了,它可以工作。
我更改了证明代码中的包和类名,因为我不能共享我的公司和类名。我希望这个答案能对那些有同样问题的人有所帮助。
- 如何在CMake中自动链接本地生成的库或导入的库
- 在 win32 上生成 R 包:无法加载共享对象 (.dll)
- Clang 是否可以在使用可见性属性时生成导入库(不带 __declspec(dllexport))?
- 如何使用msbuild从OBJS生成导入LIB
- 为什么cmake还为导入的包添加编译选项
- 错误:必须设置CMake工具才能生成.在工具包选项中配置CMake工具
- 如何为Visual Studio C++项目重新生成包目录
- 如何在编译时已知 N 的C++中生成从 0 到 N 的size_t包
- 如何将 Cython 生成的模块从 python 导入到 C/C++ 主文件?(C/C++编程)
- 使用工程空间在软件包中导入的线性代数库EIGEN
- 使用参数包扩展生成constexpr
- MSBuild 用于在生成时将 nuget 包应用于项目
- 如何在 Linux 上将所有第三方运行时依赖项包含在 cmake/cpack 生成的包中
- 如何将我的生成文件项目导入QtCreator
- 如何将版本号从git标签传输到CPACK生成的源软件包
- C++生成器生成项目包
- 在 CMake 中导入的外部 msproject 不会生成
- 从模板包生成大小为 N 的所有子包
- 将从不同模块和包生成的类导入到当前类中
- 当导入swig生成的模块时,Python会报错缺少delete方法