Java'da std::vector
sarma için uygun taban türü java.util.AbstractList
'dur. java.util.Vector
'u bir temel olarak kullanmanız garip olurdu çünkü iki depolama alanıyla, bir tane std::vector
, biri de java.util.Vector
.
you can't have AbstractList<double>
in Java, bu (double
ilkel türüdür oysa Object
den Double
devralır) AbstractList<Double>
olmak zorunda çünkü yudum olsa sizin için bu yapmaz nedenidir.
Tüm bunları, bir araya getirdiğimi söyledikten sonra, std::vector<double>
ve std::vector<std::vector<double> >
'u Java'da güzel bir şekilde sarar. Tamamlanmadı, ancak Java'daki yineleme stilini ve öğeler üzerinde set()
/get()
'u destekler. Başka şeyleri nasıl/ne zaman istediğiniz gibi uygulayacağınızı göstermek için yeterli olmalıdır.
Arabirim dosyasında gittiğimiz bölümlerde konuşacağız, ancak temel olarak hepsi sıralı ve tamamlanmış olacak. Bizim modülü num
tanımlayan num.i
ile başlayarak
: test etmek için
%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) jniclasscode=%{
static {
try {
System.loadLibrary("num");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. \n" + e);
System.exit(1);
}
}
%}
Biz fonksiyonların oluşturulan num_wrap.cxx
ve iki uygulamaları için #include
s var (onlar sadece dışarı burada onları koymak ayrı bir dosyada olabilir laziness/kolaylık).
Ayrıca, paylaşılan nesne/DLL'nin arabirimin kullanıcısı için saydam olarak yüklenmesine neden olmak için Java SWIG arabirimlerinde kullanmaktan hoşlandığım %pragma(java) jniclasscode=
ile bir numara da var.
Arabirim dosyasında sonraki kısım, std::vector
parçalarının sarılmasıdır. SWIG söyler
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;
}
}
};
}
ana değişim burada %rename(size_impl) size;
, bunun yerine size_impl
olarak std::vector
den size()
ortaya çıkarmak için: Biz birkaç değişiklik yapmak gerekir çünkü std_vector.i
kullanmıyorum.Java std::vector
sürümü daha olası int
olmayacak bir size_type
döndürür gibi bir int
dönmek size
beklediğini çünkü bunu yapmak gerekir.
%typemap(javabase) std::vector<double> "java.util.AbstractList<Double>"
%typemap(javainterface) std::vector<double> "java.util.RandomAccess"
%typemap(javacode) 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(javacode) 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;
}
%}
Bu bir üs ayarlar: arayüz dosyasında
Sonraki kadar biz uygulamak istiyoruz yanı sıra uyumsuz türleri ile fonksiyonlar arasındaki şeyleri zorlamak için bazı ekstra Java kod yazarken neyi temel sınıf ve arayüzleri söylemek std::vector<std::vector<double> >
için std::vector<double>
ve java.util.AbstractList<Vector>
için java.util.AbstractList<Double>
sınıf (Vector
arayüzün Java tarafında std::vector<double>
arayacaktır budur).
Ayrıca, Java tarafında, double
ile Double
dönüşümünü ve geri dönmesini sağlayan get
ve set
uygulamalarını da sağlıyoruz. arayüzde
Son olarak biz ekleyin:
namespace std {
%template(Vector) std::vector<double>;
%template(Matrix) std::vector<vector<double> >;
}
std::vector<double> testVec();
std::vector<std::vector<double> > testMat();
Bu Matrix
olarak std::vector<vector<double> >
için benzer Vector
olarak (belirli tip) std::vector<double>
bakın ve SWIG söyler. Ayrıca, SWIG'e iki test fonksiyonumuzu göstermesini söyleriz.
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();
}
}
}
inşa etmek ve yaptığımız bu çalıştırın: Java
Sonraki kadar, test.java
, basit main
biraz kodumuzu egzersiz
swig -java -c++ num.i
g++ -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.so
javac test.java && LD_LIBRARY_PATH=. java test
Ben sürümü 4.4 g ++ ile bu test ve Linux/x86 üzerinde SWIG 1.3.40.
num.i
tam sürümü here bulunabilir, ancak her zaman parçanın her birini tek bir dosyaya yapıştırarak bu yanıttan her zaman yeniden oluşturulabilir. Ben AbstractList
den uygulanmadı ettik
şeyler:
add()
- push_back()
yoluyla uygulanabilir, varsayılan olarak uyumlu bir şeyi uygulamak için çalışır hatta std_vector.i ama Double
double
vs ile çalışmıyor sorun veya AbstractList
belirtilen dönüş türü maç
remove()
(modCount
artırmayı unutmayın etmeyin) - büyük değil std::vector
zamanı karmaşıklığı açısından, ama imkansız değil ya (aynı şekildeile uygulamak)
- Başka bir
Collection
gerektiren bir kurucunun kullanılması önerilir, ancak burada uygulanmamıştır. Aynı yerde set()
ve get()
uygulanabilir, ancak oluşturulan kurucuyu doğru şekilde adlandırmak için $javaclassname
gerekir.
- this gibi,
size_type
->int
dönüşümünün size()
numaralı sürümde olduğunu kontrol etmek isteyebilirsiniz.
Bir SWIG kullanıcısı değil, fakat std_vector.i'ye baktığımda (bunun çevrimiçi sürümlerini zaten bulabilirim), 'size()' 'imzasız bir int 'olması gerekiyordu ve SWIG'nin bunu çevirmesi gerekiyordu. Java 'uzun' için. Negatif boyutlar alıyorsanız, saf saçmalık mı, yoksa imzasız olarak imzalıyor gibi mi görünüyorlar? –