del*_*ita 8 c++ java java-native-interface swig
我用std::mapC++ 实现了一个类,并使用SWIG创建了接口,以便从Java调用.但是没有迭代器对象允许我遍历SWIG包中的条目std::map.有谁知道如何创建迭代器?
Fle*_*exo 12
为了能够在Java中迭代一个Object,它需要实现Iterable.这又需要一个调用的成员函数iterator(),它返回一个合适的实现Iterator.
从你的问题来看,你不清楚你在地图中使用的是什么类型,以及你是否希望能够迭代对(如在C++中),键或值.三种变体的解决方案基本相似,下面我的例子选择了值.
首先,我用来测试这个SWIG接口文件的前导码:
%module test
%include "std_string.i"
%include "std_map.i"
Run Code Online (Sandbox Code Playgroud)
为了实现可迭代的映射,我已经声明,定义并包装了SWIG接口文件中的另一个类.这个类为我们MapIterator实现了Iterator接口.它是Java和包装C++的混合体,其中一个比另一个更容易编写.首先是一些Java,一个类型映射,它给它实现的接口,然后是Iterable接口所需的三个方法中的两个,作为一个typemap:
%typemap(javainterfaces) MapIterator "java.util.Iterator<String>"
%typemap(javacode) MapIterator %{
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public String next() throws java.util.NoSuchElementException {
if (!hasNext()) {
throw new java.util.NoSuchElementException();
}
return nextImpl();
}
%}
Run Code Online (Sandbox Code Playgroud)
然后我们提供C++部分MapIterator,它有一个私有实现,除了异常抛出部分next()和迭代器所需的状态(用std::map自己的方式表示const_iterator).
%javamethodmodifiers MapIterator::nextImpl "private";
%inline %{
struct MapIterator {
typedef std::map<int,std::string> map_t;
MapIterator(const map_t& m) : it(m.begin()), map(m) {}
bool hasNext() const {
return it != map.end();
}
const std::string& nextImpl() {
const std::pair<int,std::string>& ret = *it++;
return ret.second;
}
private:
map_t::const_iterator it;
const map_t& map;
};
%}
Run Code Online (Sandbox Code Playgroud)
最后,我们需要告诉SWIG std::map我们正在包装实现Iterable接口并为包装目的提供额外的成员函数,std::map它返回MapIterator我们刚写的类的新实例:
%typemap(javainterfaces) std::map<int,std::string> "Iterable<String>"
%newobject std::map<int,std::string>::iterator() const;
%extend std::map<int,std::string> {
MapIterator *iterator() const {
return new MapIterator(*$self);
}
}
%template(MyMap) std::map<int,std::string>;
Run Code Online (Sandbox Code Playgroud)
这可能更通用,例如用宏来隐藏地图的类型,这样如果你有多个地图,那么就像你一样"调用"适当地图的宏%template.
原始类型的地图也有轻微的复杂性 - 你需要安排Java方使用Double/ Integer代替double/ int(自动装箱,我相信是这个术语),除非你决定已经包装对,在这种情况下你可以制作一个与原始成员配对.
| 归档时间: |
|
| 查看次数: |
1834 次 |
| 最近记录: |