std::vectorJava中自动换行的基本类型为
java.util.AbstractList。使用
java.util.Vector,因为你有两套存储,一个在最终的基地将是奇数
std::vector,还有一个在
java.util.Vector。
但是,SWIG不为您执行此操作的原因是因为您AbstractList<double>在Java中无法做到这一点,它必须是
AbstractList<Double>(
Double继承自
Objectwhile
double是原始类型)。
说了这么多我已经把一个小例子,它包装
std::vector<double>并`std::vector<std::vector
很好地在Java中。它还不完整,但是它支持Java和set()/get()`on元素中的“ for
each”迭代样式。足以说明如何/在需要时实施其他事情。
我将逐步介绍接口文件,但基本上,它们将是连续且完整的。
与开始
num.i定义我们的模块
num:
%module num%{#include <vector>#include <stdexcept>std::vector<double> testVec() { return std::vector<double>(10,1.0);}std::vector<std::vector<double> > testMat() { return std::vector<std::vector<double> >(10, testVec());}%}%pragma(java) jniclasspre=%{ static { try { System.loadLibrary("num"); } catch (UnsatisfiedlinkError e) { System.err.println("Native pre library failed to load. n" + e); System.exit(1); } }%}我们有
#include用于生成的s
num_wrap.cxx和两个用于测试的函数的实现(它们可能在单独的文件中,出于懒惰/方便的考虑,我将其放在此处)。
%pragma(java) jniclasspre=我喜欢在Java SWIG接口中使用一个技巧,以使接口的用户透明地加载共享库/ DLL。
接口文件中的下一部分是
std::vector我们要包装的部分。我没有使用,
std_vector.i因为我们需要进行一些更改:
namespace std { template<class T> class vector { public: typedef size_t size_type; typedef T value_type; typedef const value_type& const_reference; %rename(size_impl) size; vector(); vector(size_type n); size_type size() const; size_type capacity() const; void reserve(size_type n); %rename(isEmpty) empty; bool empty() const; void clear(); void push_back(const value_type& x); %extend { const_reference get_impl(int i) throw (std::out_of_range) { // at will throw if needed, swig will handle return self->at(i); } void set_impl(int i, const value_type& val) throw (std::out_of_range) { // at can throw self->at(i) = val; } } };}这里是主要的变化
%rename(size_impl)size;,它告诉SWIG暴露
size()从
std::vector作为
size_impl代替。我们需要这样做,因为Java期望
size返回一个
int地方,因为
std::vector版本返回的地方
size_type很可能不会返回
int。
接下来在接口文件中,我们告诉我们要实现什么基类和接口,以及编写一些额外的Java代码以强制具有不兼容类型的函数之间的工作:
%typemap(javabase) std::vector<double> "java.util.AbstractList<Double>"%typemap(javainterface) std::vector<double> "java.util.RandomAccess"%typemap(javapre) std::vector<double> %{ public Double get(int idx) { return get_impl(idx); } public int size() { return (int)size_impl(); } public Double set(int idx, Double d) { Double old = get_impl(idx); set_impl(idx, d.doublevalue()); return old; }%}%typemap(javabase) std::vector<std::vector<double> > "java.util.AbstractList<Vector>"%typemap(javainterface) std::vector<std::vector<double> > "java.util.RandomAccess"%typemap(javapre) std::vector<std::vector<double> > %{ public Vector get(int idx) { return get_impl(idx); } public int size() { return (int)size_impl(); } public Vector set(int idx, Vector v) { Vector old = get_impl(idx); set_impl(idx, v); return old; }%}这设置了
java.util.AbstractList<Double>for
std::vector<double>和
java.util.AbstractList<Vector>for
的基类`std::vector<std::vector
(这Vector是我们将std::vector`在接口的Java端调用的基类)。
我们还在Java方面提供
get和的实现
set,可以处理
double到
Double转换并再次返回。
最后,在界面中添加:
namespace std { %template(Vector) std::vector<double>; %template(Matrix) std::vector<vector<double> >;}std::vector<double> testVec();std::vector<std::vector<double> > testMat();这告诉SWIG指
std::vector<double>(与特定类型),其
Vector同样地,对于`std::vector<vector
如Matrix`。我们还告诉SWIG公开我们的两个测试功能。
接下来
test.java,,这
main是Java中的一个简单示例,它可以稍微练习一下我们的代码:
import java.util.AbstractList;public class test { public static void main(String[] argv) { Vector v = num.testVec(); AbstractList<Double> l = v; for (Double d: l) { System.out.println(d); } Matrix m = num.testMat(); m.get(5).set(5, new Double(5.0)); for (Vector col: m) { for (Double d: col) { System.out.print(d + " "); } System.out.println(); } }}要构建并运行它,我们要做:
swig -java -c++ num.ig++ -Wall -Wextra num_wrap.cxx -shared -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux/ -o libnum.sojavac test.java && LD_LIBRARY_PATH=. java test
我在Linux / x86上使用g ++版本4.4和SWIG 1.3.40对此进行了测试。
的完整版本
num.i可以在此处找到,但始终可以通过将每个部分粘贴到一个文件中来从此答案中重建。
我尚未实现的事情
AbstractList:
add()
-可以通过push_back()
,std_vector.i来实现,默认情况下甚至尝试实现兼容的东西,但是它不适用于Double
vsdouble
问题或与AbstractList
(不要忘记增加modCount
)中指定的返回类型匹配remove()
-std::vector
就时间复杂度而言不是很好,但也不是不可能实现(同样使用modCount
)Collection
建议使用另一个构造函数,但此处未实现。可以在同一个地方执行set()
和get()
是的,但需要$javaclassname
正确地命名生成的构造函数。- 您可能想使用类似这样的方法来检查
size_type
->int
转换size()
是否正确。



