""" true julia> cxx""" std::vector a = std::vector

Convert vector Cxx to Julia vector

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> >) {
}

      

The above code, when entered into the Julia terminal, shows that there is vector data. However, I would prefer to completely move it to the Julia array. What's the best way to do this?

Note. In the end, the shared library will return std::vector<int>

, so the question, more specifically, is how best to convert std::vector<int>

to a standard Julia vector. (This refers to the variable b

in the example code).

Thanks in advance.

EDIT: The reason why the problem occurs seems unclear, so hopefully the following will help (it follows directly from the code above)

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!

      

Regardless of how you try to pass the julia reference variable, it cannot be parsed back into the C ++ environment (and the latter completely ruined julia). You cannot use the same methods as for using C ++ references in julia. Trying to capture the pointer or the b

, @b

, b[0]

, or &b[0]

and dismantle these works.

+3


source to share


3 answers


Thanks to Jeff Besancon and Isaiah for their answers ( icxx" &a[0]; "

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

accordingly)

To put everything together in one answer, I made the following example:



# 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).

      

Hope this helps others who are in the same situation.

+1


source


If copying the data is ok, you can call collect

on the C ++ vector to copy it into the julia vector. If you want to avoid copying, you can get the address of the data with icxx"&a[0];"

and wrap it with unsafe_wrap

.



+6


source


The question here is still not clear, but when answering the change: pass the CppValue

Julia variable back to icxx

, use interpolation. For example:

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

      

As far as "spaces" are concerned, I don't believe Example 8 or the docs at all constitute a normative variable declaration statement, but in general Julia references might be more convenient to use with Julia code. The examples given in Jeff's answer are the solution to make a shell without a copy. For working with data declared as std::vector

, the options I know of are: copy, wrap the pointer, or use the provided overloads getindex

to handle the data as a Julia array (0 based) (which makes the pointer-scope automatically and shouldn't have any overhead costs).

0


source







All Articles