2017-06-27 4 views
3
julia> using Cxx 
julia> cxx""" #include <vector> """ 
true 
julia> cxx""" std::vector<int> a = std::vector<int> (5,6); """ 
true 
julia> icxx""" a[0]; """ 
(int &) 6 
julia> b = icxx""" a; """ 
(class std::vector<int, class std::allocator<int> >) { 
} 
julia> b[0] 
6 
julia> b 
(class std::vector<int, class std::allocator<int> >) { 
} 

上記のコードは、Julia端末に入力すると、ベクターデータが存在することを示しています。しかし、私はそれをJulia配列に完全に移すことを好むでしょう。これを行う最善の方法は何ですか?Cxxベクターをジュリアベクターに変換する

注:は、最終的に共有ライブラリがstd::vector<int>を返すされますので、ご質問は、より明確に、標準ジュリアベクターにstd::vector<int>を変換する方法が最善です。 (これは、例コードの変数bを参照しています)。

ありがとうございます。

EDIT

:問題は、そううまくいけば、次のことが役立つ明確ではないようですが、なぜのための推論が

julia> unsafe_wrap(Array, pointer(b), length(b)) 
ERROR: MethodError: objects of type Ptr{Int32} are not callable 
julia> @cxx b; 
ERROR: Could not find `b` in translation unit 
julia> cxx" b; " 
In file included from :1: 
__cxxjl_17.cpp:1:2: error: C++ requires a type specifier for all declarations 
b; 
^ 
true 
julia> icxx" b; " 
ERROR: A failure occured while parsing the function body 
julia> cxx" &b; " 
In file included from :1: 
__cxxjl_15.cpp:1:3: error: C++ requires a type specifier for all declarations 
&b; 
^
__cxxjl_15.cpp:1:3: error: declaration of reference variable 'b' requires an initializer 
&b; 
^
true 
julia> icxx" &b; " 
ERROR: A failure occured while parsing the function body 
julia> @cxx &b; 
LLVM ERROR: Program used external function 'b' which could not be resolved! 

を(それは上記のコードから直接に続く)どんなにjulia参照変数を渡そうとすると、C++環境に解析することはできません(最後のものはjuliaを完全に破棄しました)。また、juliaにC++参照を渡すのに使用された同じメソッドを使用することもできません。 b@bb[0]または&b[0]のいずれかのポインタをつかみ、それらの作業を解析しようとしています。

+1

'test/std.jl'を読んでください。 'v = icxx" std :: vector {2、4、6、8、10、12、14}; ";' unsafe_wrap(配列、ポインタ(v)、長さ(v) 。 –

+0

@Isaiah変数参照がC++空間から始まり、julia空間に移動したので、これはうまくいきます。 Cxx.jのドキュメントでは、例8は、C++変数がジュリアの参照として(ジュリア空間で)直接格納されることを推奨しています。ここから、データを標準ジュリア配列に転送することは不可能であると思われます。あなたの例は変数 'a'に似ていますが、変数' b'の変換は問題のものです。 – user3303504

答えて

1

おかげで(icxx" &a[0]; " & sum = icxx""" std::accumulate($b.begin(), $b.end(), 0); """それぞれ)

# Converting between Julia and C++ 
using Cxx 
cxxinclude("vector") 
cxx" std::vector<int> a = std::vector<int> (5,6); " 
# Transfer variable from C++ space to julia space "as is" 
b = @cxx a; 

# Pass the raw data reference from the C++ variable into julia space 
c = icxx" &a[0]; " # From C++ space 
d = icxx" &$b[0]; " # From julia space, only difference is the '$' interpolation 

# Get the number of elements in the vector 
cSize = icxx" a.size(); " 
dSize = icxx" $b.size(); " 

# Convert to a standard julia array 
juliaArray_c = unsafe_wrap(Array, c, cSize, true) 
juliaArray_d = unsafe_wrap(Array, d, dSize, true). 

うまくいけば、これは他の人に役立ちます同じ状況にあります。

6

データをコピーすることが可能な場合は、C++ベクターでcollectを呼び出して、ジュリアベクターにコピーすることができます。コピーを避けたい場合は、icxx"&a[0];"でデータのアドレスを取得し、unsafe_wrapを使用してそのアドレスをラップしてください。私は、次の例を作った一つの答えに一緒にすべてを組み合わせるためにその答えのためのジェフBezanson &イザヤに

+0

可能であれば、データをコピーしないことをお勧めします。 2番目の答え( 'icxx" &a[0]; "')は、私がその質問の後に行ったことではありません。私は変数 'b'を変換しようとしています。私は役に立たないもので遊ぶために 'g(x、y、z)= unsafe_wrap(Array、convert(Ptr {x}、pointer_from_objref(y))、z、false)'を使って答えを適応させようとしました。アドレスは正しいように見え、個々にこのメソッドが機能します。しかし、私はそれらを反復することはできません。何か案は? – user3303504

+0

質問にさらに詳しい情報が記載されています。 – user3303504

+0

ポインタの引数として '&a [0]'の結果を 'unsafe_wrap'に渡す必要があります。ベクトルにインデックスを付けると、整数が引き出され、その整数オブジェクトへのポインタがラップされます。これはあなたが望むものではありません。 –

0

ここでの質問はまだわかりませんが、CppValueジュリア変数をicxxに戻すには補間を使用してください。例:「スペース」について

julia> cxx""" std::vector<int> a = std::vector<int> (5,6); """ 
true 

julia> b = @cxx a 
(class std::__1::vector<int, class std::__1::allocator<int> >) { 
} 

julia> typeof(b) 
Cxx.CppValue{Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{Symbol("std::__1::vector")},Tuple{Int32,Cxx.CxxQualType{Cxx.CppTemplate{Cxx.CppBaseType{Symbol("std::__1::allocator")},Tuple{Int32}},(false, false, false)}}},(false, false, false)},24} 

julia> cxxinclude("numeric") 

julia> sum = icxx""" std::accumulate($b.begin(), $b.end(), 0); """ 
30 

、私は、例えば、8または一般にドキュメントが変数の宣言についての規範的な文を作るが、一般的に言って、ジュリアの参照がジュリアのコードで使用する方が便利かもしれ信じていません。 。 Jeffの答えにある例は、ノーコピーラッパーを作成するソリューションです。 std::vectorとして宣言されているデータを処理するには、コピー、ラップ、またはgetindexオーバーロードを使用してデータを(0ベースの)Julia配列として扱います(ポインタラッピングを自動的に行い、オーバーヘッドはありません)。

+1

ああ!補間はすべての違いを作ります。 julia> ptr = icxx "" "&$b[0];" "、" julia> size = icxx "" "$ b.size();" "'と 'julia> juliaArray = unsafe_wrap(Array、ptr)を追加すると、 、size、true) 'を入力すると、元の質問に完全に答えることができます。ありがとう=) – user3303504

関連する問題