栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

SWIG(v1.3.29)生成了C ++到Java Vector类,无法正常运行

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SWIG(v1.3.29)生成了C ++到Java Vector类,无法正常运行

std::vector
Java中自动换行的基本类型为
java.util.AbstractList
。使用
java.util.Vector
,因为你有两套存储,一个在最终的基地将是奇数
std::vector
,还有一个在
java.util.Vector

但是,SWIG不为您执行此操作的原因是因为您AbstractList<double>在Java中无法做到这一点,它必须是

AbstractList<Double>
Double
继承自
Object
while
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

  1. add()
    -可以通过
    push_back()
    ,std_vector.i来实现,默认情况下甚至尝试实现兼容的东西,但是它不适用于
    Double
    vs
    double
    问题或与
    AbstractList
    (不要忘记增加
    modCount
    )中指定的返回类型匹配
  2. remove()
    -
    std::vector
    就时间复杂度而言不是很好,但也不是不可能实现(同样使用
    modCount
  3. Collection
    建议使用另一个构造函数,但此处未实现。可以在同一个地方执行
    set()
    get()
    是的,但需要
    $javaclassname
    正确地命名生成的构造函数。
  4. 您可能想使用类似这样的方法来检查
    size_type
    ->
    int
    转换
    size()
    是否正确。


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/495651.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号