将Cxx Vector转换为Julia Vector

时间:2017-06-27 18:00:47

标签: c++ vector type-conversion julia

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数组中。这样做的最佳方法是什么?

注意:最终共享库将返回std::vector<int>,因此更明确的问题是如何最好地将std::vector<int>转换为标准的Julia向量。 (这是指示例代码中的变量b)。

提前致谢。

编辑:出现问题的原因似乎并不清楚,所以希望以下内容有所帮助(直接来自上面的代码)

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)。也不能使用用于将c ++引用传递到julia的相同方法。试图抓住b@bb[0]&b[0]的指针并解析这些工作。

3 个答案:

答案 0 :(得分:6)

如果可以接受复制数据,可以在C ++向量上调用collect将其复制到julia向量。如果您想避免复制,可以使用icxx"&a[0];"获取数据的地址,并使用unsafe_wrap将其包装。

答案 1 :(得分:2)

感谢Jeff Bezanson&amp;以赛亚的答案分别为icxx" &a[0]; "&amp; 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).

希望这有助于处于相同情况的其他人。

答案 2 :(得分:0)

这里的问题仍然不清楚,但回应编辑:将CppValue Julia变量传回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

关于&#34;空格&#34;,我不相信例8,或者文档一般会对变量声明做出规范性声明,但一般来说,Julia引用可能更方便与Julia代码一起使用。 Jeff的答案中给出的例子是制作无副本包装器的解决方案。要使用声明为std::vector的数据,我知道的选项是:复制,包装指针,或使用提供的getindex重载将数据视为基于(0的)Julia数组(它自动执行指针包装,并且没有开销。)