У меня есть некоторый код C ++, который имеет существующие привязки Python, и я пытаюсь привить его Джулии с помощью PyCall. Одна из вызываемых функций генерирует указатель на двумерный массив в памяти, в который я хотел бы обернуть массив Джулии, чтобы я мог добавить / вычесть / умножить на скаляры и т. Д. Я знаю размер массива и в настоящее время он представлен в виде PyObject, к которому я могу сделать x_ptr[1]
, x_ptr[2]
и получить правильные значения. Но я хотел бы иметь массив, x
,
Вот простой пример использования numpy. По умолчанию PyCall преобразует массивы NumPy в массивы Джулии, но мы можем предотвратить это с помощью @pycall
и ::Any
аннотация, чтобы показать, как вы бы сделали это вручную. Вам нужно покопаться в объекте, чтобы найти этот указатель.
julia> obj = @pycall numpy.reshape(numpy.arange(20), (4,5))::Any
PyObject array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
julia> array_interface = obj[:__array_interface__]
Dict{Any,Any} with 6 entries:
"shape" => (4, 5)
"strides" => nothing
"typestr" => "<i8""data" => (4705395216, false)
"descr" => Tuple{String,String}[("", "<i8")]
"version" => 3
julia> array_interface["data"] # This is the actual pointer!
(4705395216, false)
julia> unsafe_wrap(Matrix{Int}, Ptr{Int}(array_interface["data"][1]), reverse(array_interface["shape"]))
5×4 Array{Int64,2}:
0 5 10 15
1 6 11 16
2 7 12 17
3 8 13 18
4 9 14 19
Конечно, я не знаю, как ваш объект python хранит свой указатель. Вам придется копаться в вашем объекте Python, чтобы найти этот указатель самостоятельно.
Других решений пока нет …