std :: vector到java.util.Vector使用swig生成代码 [英] std::vector to java.util.Vector code generation with swig

查看:679
本文介绍了std :: vector到java.util.Vector使用swig生成代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试用SWIG生成java代码

I try to generate java code with SWIG

MyList.h 中,我声明了一个名为 _list

In MyList.h I declared a custom list object called _list

List<T*> _list;

,此List类继承自向量

and this List class inherits from vector

class List : public vector<T>

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

In a business class (in C++) I return a List of custom objects

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

所以我想生成java代码,我可以检索这个C ++列表为java .util.List或java.util.Vector。

so I want to generate java code where I can retrieve this C++ List as java.util.List or java.util.Vector.

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

in my swig.i file I couldn't manage how to embody

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

任何类型都有助于如何配置此swig.i模板文件或一些示例代码生成一个java.util.List / Vector返回函数。

any kind help how to configure this swig.i template file or some sample code to generate a java.util.List / Vector returning function will be appreciated.

谢谢。

推荐答案

你真的不想触摸 java.util.Vector 与你的包装接口,因为你会最终复制存储或做大每次传入/传出函数时的复制操作数。 (注意,一般来说,在C ++从容器继承是奇怪的设计)。

You don't really want to be touching java.util.Vector with your wrapped interfaces because you will end up duplicating storage or making large numbers of copy operations every time you pass it in/out of a function. (Note also that in general in C++ inhering from containers is odd design).

而在Java中,正确的事情是继承自 java.util.AbstractList 。此答案是我的类似问题的较旧答案的更通用版本。

Instead in Java the "right" thing to do is to inherit from java.util.AbstractList. This answer is a more generic version of my older answer to a similar question.

它适用于所有 std :: vector 类型,而不仅仅是一个固定类型和句柄需要使用autobox自定义类型映射来访问对象的原语。它缺少对专门的 std :: vector< bool> 的支持,但是如果你需要它应该很容易添加。

It works for all std::vector types, not just a fixed type and handles primitives which need to be accessed via Objects using an "autobox" custom type map. It's missing support for the specialized std::vector<bool>, but that should be simple to add if you need it.

%{
#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 类型,有一个超载速度更快)。

Most of this is fairly similar to the default std_vector.i that SWIG currently provides, the new bits are the renaming, extending and typemaps that extend AbstractList and implement RandomAccess. It also adds a constructor that takes other Collections - this is recommended by the Java documentation and easy enough to do. (There's an overload for other std::vector types which is much faster).

我在另一个SWIG界面内测试了这个向量包装:

I tested this vector wrapping within another SWIG interface:

%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);
    }
  }
}

这篇关于std :: vector到java.util.Vector使用swig生成代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆