Конвертировать Cxx 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> >) {
}

Приведенный выше код при вводе в терминал Julia показывает наличие векторных данных. Однако я бы предпочел полностью перенести его в массив Julia. Каков наилучший способ сделать это?

Замечания: В конце концов общая библиотека будет возвращать std::vector<int>Таким образом, вопрос, более четко, как лучше всего конвертировать std::vector<int> в стандартный вектор Джулия. (Это относится к переменной 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, @b, b[0] или же &b[0] и разбор этих работ.

3

Решение

Если копирование данных приемлемо, вы можете позвонить collect на вектор C ++, чтобы скопировать его в вектор Джулии. Если вы хотите избежать копирования, вы можете получить адрес данных с помощью icxx"&a[0];" и обернуть, используя unsafe_wrap,

6

Другие решения

Спасибо Джеффу Безансону & Исайя за свои ответы (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).

Надеюсь, это поможет другим, которые находятся в такой же ситуации.

2

Вопрос здесь до сих пор неясен для меня, но отвечая на правку: пройти 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 или документы в целом делают нормативное заявление об объявлении переменных, но, вообще говоря, ссылки Julia могут быть более удобными для использования с кодом Julia. Приведенные примеры в ответе Джеффа — это решение сделать обертку без копии. Для работы с данными, объявленными как std::vectorя знаю следующие варианты: скопировать, обернуть указатель или использовать getindex перегрузки для обработки данных как массива Julia (основанного на 0) (который выполняет автоматическое перенос указателя и не должен иметь служебных данных).

0
По вопросам рекламы [email protected]