java - std::vector 使用 swig 生成 java.util.Vector 代码

标签 java c++ list vector swig

我尝试用 SWIG 生成 java 代码

MyList.h 中,我声明了一个名为 _list 的自定义列表对象

List<T*> _list;

并且这个List类继承自vector

class List : public vector<T>

在业务类中(在 C++ 中)我返回一个自定义对象列表

List<MyObject> getMyList(){
   ....
   return list;
}

所以我想生成 java 代码,我可以在其中检索此 C++ 列表作为 java.util.List 或 java.util.Vector。

在我的 swig.i 文件中,我无法管理如何体现

%typemap(jstype) List "java.util.Vector"
namespace std {
   %template(CustomVector) vector<MyObject>;
}

任何类型的帮助如何配置此 swig.i 模板文件或一些示例代码以生成 java.util.List/Vector 返回函数将不胜感激。

谢谢。

最佳答案

你真的不想触摸java.util.Vector使用包装的接口(interface),因为每次将它传入/传出函数时,最终都会复制存储或进行大量复制操作。 (另请注意,通常在 C++ 中从容器继承是奇怪的设计)。

相反,在 Java 中,“正确”的做法是继承自 java.util.AbstractList .这个答案是我的 older answer to a similar question 的更通用版本.

它适用于所有 std::vector类型,而不仅仅是固定类型和句柄 primitives which need to be accessed via Objects使用“autobox”自定义类型映射。它缺少对专业 std::vector<bool> 的支持,但如果需要,添加起来应该很简单。

%{
#include <vector>
#include <stdexcept>
%}

%include <stdint.i>
%include <std_except.i>

namespace std {

    template<class T> class vector {
      public:
        typedef size_t size_type;
        typedef T value_type;
        typedef const value_type& const_reference;
        vector();
        vector(size_type n);
        vector(const vector& o);
        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(int i) const throw (std::out_of_range) {
                return $self->at(i);
            }
            value_type set(int i, const value_type& VECTOR_VALUE_IN) throw (std::out_of_range) {
                const T old = $self->at(i);
                $self->at(i) = VECTOR_VALUE_IN;
                return old;
            }
            int32_t size() const {
              return $self->size();
            }
            void removeRange(int32_t from, int32_t to) {
              $self->erase($self->begin()+from, $self->begin()+to);
            }
        }
    };
}

// Java typemaps for autoboxing in return types of generics
%define AUTOBOX(CTYPE, JTYPE)
%typemap(autobox) CTYPE, const CTYPE&, CTYPE& "JTYPE"
%enddef
AUTOBOX(double, Double)
AUTOBOX(float, Float)
AUTOBOX(boolean, Boolean)
AUTOBOX(signed char, Byte)
AUTOBOX(short, Short)
AUTOBOX(int, Integer)
AUTOBOX(long, Long)
AUTOBOX(SWIGTYPE, $typemap(jstype,$1_basetype))

%typemap(javabase) std::vector "java.util.AbstractList<$typemap(autobox,$1_basetype::value_type)>"
%typemap(javainterface) std::vector "java.util.RandomAccess"
%typemap(jstype) std::vector get "$typemap(autobox,$1_basetype)"
%typemap(jstype) std::vector set "$typemap(autobox,$1_basetype)"
%typemap(jstype) std::vector &VECTOR_VALUE_IN "$typemap(autobox,$1_basetype)"
%typemap(javacode) std::vector %{
  $javaclassname(java.util.Collection<$typemap(autobox,$1_basetype::value_type)> e) {
    this.reserve(e.size());
    for($typemap(autobox,$1_basetype::value_type) value: e) {
      this.push_back(value);
    }
  }
%}

其中大部分与 SWIG 当前提供的默认 std_vector.i 非常相似,新位是重命名、扩展和扩展 AbstractList 的类型映射。并实现 RandomAccess .它还添加了一个采用其他 Collection 的构造函数s - 这是 Java 文档推荐的并且很容易做到。 (其他 std::vector 类型有重载,速度)。

我在另一个 SWIG 接口(interface)中测试了这个 vector 包装:

%module test

%include "vector.i"

%template(DblVec) std::vector<double>;
%template(ByteVec) std::vector<signed char>;
%include <std_string.i>
%template(StringVec) std::vector<std::string>;

%inline %{
struct foo {};
%}

%template(FooVec) std::vector<foo>;

我能够编译和运行的是:

public class run {
  public static void main(String argv[]) {
    System.loadLibrary("test");
    DblVec dv = new DblVec(100);
    for (int i = 0; i < 100; ++i) {
      dv.set(i,(double)i);
    }
    FooVec fv = new FooVec(1);
    fv.set(0, new foo());
    for (double d: dv) {
      System.out.println(d);
    }
  }
}

关于java - std::vector 使用 swig 生成 java.util.Vector 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10596052/

相关文章:

java - 在复杂的定界符上有条件地拆分字符串

java - 单例程序中Static语句的使用和流程

c++ - 如何将重载函数传递给运算符(operator)?

c++ - 在 C/C++ 中的 Linux 上使用 openssl 的 HTTPS

arrays - 将数组映射到 kotlin 对象列表

java - snmpv3 上的 EngineId

java - 在java代码中加载网络路径

c++ - 从 C++ 中的默认浏览器读取 cookie

list - 编译时强制有限列表

c# - List<T> 中的 Contains 和 Exists 有什么不同?