SWIG 3.0.8'de, C++ - Java haritasındaki std::list
için hiçbir uygulama yoktur, yalnızca std::vector
. Bu çoğu vaka için çok uygun değil, bu yüzden kendi SWIG tanımımı std::list
oluşturmak mümkün olup olmadığını merak ediyordum ve nasıl yaparım?std :: list <std::string> listesi için, UTIG'de C++ 'da Java için <String> Listesinin nasıl bir örnek haritası oluşturursunuz?
cevap
Sadece Java'da std::list
'u sarmak için çalışacak bir dizi typemaps yazdım. java.util.AbstractSequentialList
'u bir temel sınıf olarak kullanıyorlar, bu yüzden var olan verilerin yalnızca bir kopyası var ve hem Java hem de C++ veri yapısı kadar güzel çalışıyor. Bu cevap, benzer şekilde, an older answer wrapping std::vector
'da kullandığım aynı tekniklerin bir iyileştirme ve bağlantı noktasıdır. Şimdi bunu oldukça fazla yeniden ediyorum beri
// 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))
Sonra
ben bu kullanılmış benim aşağıdaki std_list.i dosyası:
%include <autobox.i>
%include <stdint.i>
%{
#include <list>
#include <algorithm>
%}
namespace std {
template <typename T> class list {
public:
// This typedef is a weird hack to make stuff work
typedef std::list<T>::iterator iterator;
typedef size_t size_type;
typedef T value_type;
typedef T& reference;
void assign(size_type n, const value_type &val);
bool empty() const;
list(size_type n, const value_type &value=value_type());
list(const list &o);
list();
~list();
size_type max_size() const;
void pop_back();
void pop_front();
void push_back(const value_type &x);
void push_front(const value_type &x);
void remove(const T &v);
// Possible bug: jint != size_type
jint size() const;
void sort();
%javamethodmodifiers "private";
// Only for helping implement listIterator
iterator begin();
iterator insert(iterator pos, const value_type &v);
%extend {
static void set(iterator pos, const value_type& v) {
*pos = v;
}
jint previous_index(const iterator& pos) const {
return pos == self->begin() ? -1 : std::distance(self->begin(), static_cast<std::list<T>::const_iterator>(pos));
}
jint next_index(const iterator& pos) const {
return pos == self->end() ? self->size() : std::distance(self->begin(), static_cast<std::list<T>::const_iterator>(pos));
}
static iterator next(iterator pos) {
return ++pos;
}
static iterator previous(iterator pos) {
return --pos;
}
static value_type deref(const iterator& pos) {
return *pos;
}
static void advance(iterator& pos, jint index) {
std::advance(pos, index);
}
bool has_next(const iterator& pos) const {
return pos != $self->end();
}
}
%javamethodmodifiers "public";
};
}
%typemap(javaimports) std::list %{
import java.util.AbstractSequentialList;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Collection;
%}
%typemap(javabase) std::list "AbstractSequentialList<$typemap(autobox,$1_basetype::value_type)>"
#define JAVA_VALUE_TYPE $typemap(autobox,$1_basetype::value_type)
#define JAVA_ITERATOR_TYPE $typemap(jstype, $1_basetype::iterator)
%typemap(javacode,noblock=1) std::list {
public $javaclassname(Collection c) {
this();
ListIterator<JAVA_VALUE_TYPE> it = listIterator(0);
for (Object o: c) {
it.add((JAVA_VALUE_TYPE)o);
}
}
public ListIterator<JAVA_VALUE_TYPE> listIterator(int index) {
return new ListIterator<JAVA_VALUE_TYPE>() {
private JAVA_ITERATOR_TYPE pos;
private JAVA_ITERATOR_TYPE last;
private ListIterator<JAVA_VALUE_TYPE> init(int index) {
pos = $javaclassname.this.begin();
$javaclassname.advance(pos, index);
return this;
}
public void add(JAVA_VALUE_TYPE v) {
// Technically we can invalidate last here, but this makes more sense
last=$javaclassname.this.insert(pos, v);
}
public void set(JAVA_VALUE_TYPE v) {
if (null==last) {
throw new IllegalStateException();
}
$javaclassname.set(last, v);
}
public void remove() {
if (null==last) {
throw new IllegalStateException();
}
$javaclassname.this.remove(last);
last=null;
}
public int previousIndex() {
return $javaclassname.this.previous_index(pos);
}
public int nextIndex() {
return $javaclassname.this.next_index(pos);
}
public JAVA_VALUE_TYPE previous() {
if (previousIndex() < 0) {
throw new NoSuchElementException();
}
last = pos;
pos = $javaclassname.previous(pos);
return $javaclassname.deref(last);
}
public JAVA_VALUE_TYPE next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
last = pos;
pos = $javaclassname.next(pos);
return $javaclassname.deref(last);
}
public boolean hasPrevious() {
return previousIndex() != -1;
}
public boolean hasNext() {
return $javaclassname.this.has_next(pos);
}
}.init(index);
}
}
Bu dosya çoğunlukla sadece ListIterator
uygulanması için aşağı kaynar AbstractSequentialList
, uygular. Bu biraz acımasız çünkü Java'nın bir yineleyici kavramını uyguladığı yöntem, tamamen farklı olmasa da, C++ soyutlamasına biraz farklıdır. ListIterator
ait
Bizim Java uygulaması çoğunlukla opak C++ yineleyici ve aslında gerekli gereksinimlerini karşılamak üzere std::advance
, std::distance
ve operator++
/operator--
kullanan fazladan C++ koduna aramak için bazı tutkal etrafında sarıcı olduğunu. Bir Java programcısının beklediği gibi arayüzü güvenli/sağlam kılmak için gerekli olan çeşitli kontroller yapıştırıcı içinde bulunmaktadır.
yudum arayüzü
liste aşağıdaki ana bölümden oluşmaktadır :: std için:std::list
kendisi ilgili bölümlerinin
- Beyanı. (Bazıları Java'ya uygulama detayından başka bir şey olarak bir şey ifade etmediğinden özeldir)
- Daha sonra SWIG içinde
%template
'u kullandığımızda, gereken şablon C++ yineleyici kodunu başlatmamıza izin veren bazı ekstra özel kodlar. - daha kolay Java bizim konteyner düşünür ve 'type 'Java olarak ++ yineleyici bir C opak kolu bilen türü' yazmayı yapmak
std::list
- Bazı yardımcı makroları için içe aktarma/baseclass ayarlama herhangi dahil tutar Gerekirse otomatik kutulama çok yazılır.
biz sarın her
std::list<X>
için bazı ek Java kodu:- Başka yapıcı başka bir koleksiyondan kopyalama için Java koleksiyonları arayüzü tarafından tavsiye edildiği gibi. (Bu, oldukça verimli bir şekilde yapmak için yarattığımız Java yineleyicisini kullanıyor).
ListIterator
değişkeninin tüm gereksinimlerini karşılamak için her şeyi bir arada tutan bir anonim tür döndüren soyut yönteminin bir uygulaması.noblock önişlemci makroları ne şekilde açık olan
Bu
{ }
içine sarılır, ama bu{ }
oluşturulur Java takılan almaz.Ayrıca bu Java trick to pass data to an anonymous class during construction'u kullandım (ancak bunun yerine the double brace magic kullanmış olabilir). Bunu egzersiz
%module test %include "std_list.i" %include <std_string.i> %template(DoubleList) std::list<double>; %template(StringList) std::list<std::string>;
Ve bazı gerçek Java: yerinde önüne aldığımızda
import java.util.ArrayList;
public class run {
public static void dump(java.util.AbstractCollection c) {
for (Object o: c) {
System.out.println(o);
}
}
public static void main(String[] argv) {
System.loadLibrary("test");
for (int i = 0; i < 1; ++i) {
go();
// System.gc();
}
}
public static void go() {
StringList sl = new StringList();
dump(sl);
sl.add(0,"HELLO"); // 1 arg form also worked
sl.add(1,"WORLD");
sl.add(2,"testing");
sl.add(3,"some more");
System.out.println(sl.size());
dump(sl);
sl = new StringList(new ArrayList<String>() {{
add("A");
add("B");
add("C");
}});
dump(sl);
}
}
çalışır Hangi beklendiği gibi:
swig3.0 -java -c++ -Wall test.i
javac *.java
g++ -Wall -Wextra -shared -o libtest.so test_wrap.cxx -I/usr/lib/jvm/default-java/include/ -I/usr/lib/jvm/default-java/include/linux -fPIC -D_GLIBCXX_DEBUG
LD_LIBRARY_PATH=. java run
Hips:
4
HELLO
WORLD
testing
some more
A
B
C
Rastgele bir not: hasNext()
ve ileri yineleme muhtemelen hasPrevious()
ve bu durumda int std::distance
aramayı önlemek daha kolaydır çünkü ters yineleme daha hızlıdır.
(Uyarı: ListIterator üye işlevlerinin anlamlarının ne kadar acele olması gerektiğine ilişkin Java belgelerini okudum. Bir veya birkaçını yanlış anlayabildim).
- 1. List <T> .ForEach neden listesinin değiştirilmesine izin veriyor?
- 2. Xzx1 Liste <short> için C# Döküm Listesi
- 3. Std :: atomic için ++ atomik <int>
- 4. Perl'de "% _" nedir?</p> <pre><code>@list = grep { !$_{$_}++ } @list; </code></pre> <p>tekilleştirme için bir deyim gibi:
- 5. Listesi <? MyType>
- 6. Listesi için parcelable uygulamak için nasıl parcelable yaptıklarının genelinde bir listesi geçmesine çalışıyorum <Long>
- 7. Nasıl listesi <> İki veya daha fazla özellik Nasıl List < bir öğenin dizinini bulmak için
- 8. Java: List <Object> OrientDB'de nasıl depolanır?
- 9. JRuby'yi kullanarak nasıl bir Java uygulaması oluşturursunuz?
- 10. Bir List <T>
- 11. C++ bir dizi için aşırı yüklenme operatörü << nasıl?
- 12. Nasıl Java 8 akışları ve özel Listesi ve Harita tedarikçileri ile, Harita <K, List<V>> içine Listesini <V> dönüştürmek için?
- 13. C# List <T> Test içerir
- 14. List <T> için Last() uzantı yönteminin performansı nedir?
- 15. std :: list <> :: ekleme, yineleyicileri geçersiz kılar. Gerekçe?
- 16. C# içindeki LINQ kullanarak bir Listeyi <string> bir listeye dönüştürmek için <char>
- 17. İkili Arama listesi için değil kümesi için öyle <code>Collection</code> yılında
- 18. Başlatma listesi <> Arrays.asList
- 19. std :: vector <std :: unique_ptr hatası < T >>
- 20. Tip güvenliği: List List ifadesinin, List <Object[]>
- 21. C# List <string> boş satırları nasıl kaldırılır?
- 22. C++ std :: TR1 için çalışmaz value_type: bir std tanımlama grubu :: haritası
- 23. Bir java @RequestBody Map <String, String> için örnek bir girişi nasıl el ile açıklayabilirim?
- 24. iostream için C++ sarmalayıcı sınıfı, işleçle birlikte std :: endl gibi akış değiştiricilerini kullanın <<
- 25. Java 8 java.util.function.Consumer <> için C# karşılığı nedir?
- 26. bitiştirmek karakter Java bir <code>String</code> oluşturmak üzere <code>char</code> bitiştirmek için bir yol var mı java
- 27. Tanımlanmamış şablonun örtük bir örneği 'std :: basic_string <char, std :: char_traits <char>, std :: ayırıcı <char>>'
- 28. List <String> ile <form:select> nasıl doldurulur?
- 29. Ben <code>List<T></code> var
- 30. C++ 11 Geçme 'bu' için parametresine olarak std :: Ben std :: make_shared</p> <p>Örnek kullanarak 'bu' yapıcı geçmek çalışıyorum
Kısa cevap: Muhtemelen 'Listeyi' ile eşleştirmek istemiyorsunuz, 'AbstractList''i uygulamak çok daha iyi bir fikir. Daha önce benzer konularda birkaç cevap yazdım, bakınız: http://stackoverflow.com/a/12551108/168175 http://stackoverflow.com/a/8190135/168175 –
Flexo
(Ayrıca şunu ekleyin: ['AbstractSequentialList' ] (https://docs.oracle.com/javase/7/docs/api/java/util/AbstractSequentialList.html) 'std :: list' için daha iyi bir taban sınıfıdır. Yine de istersen buraya eşdeğer bir cevap yazmaktan mutluluk duyarım. – Flexo
@Flexo Temel C++ nesnesi 'std :: list' kullanır, önceki cevaplarınızın bana nasıl yardımcı olduğu konusunda kafam karışmış mıyım? Eğer yazarsak çok memnun olurum! –