2017-11-12 17 views
1

PythonバインディングがあるC++コードがあります。PyCallを使用してJuliaに移植しようとしています。関数の1つが呼び出されると、メモリ内の2次元配列へのポインタが生成され、Julia配列をラップして、スカラーなどを加算/減算/乗算できるようになります。配列のサイズを知っています。現在のところ、私はx_ptr[1]x_ptr[2]を実行して正しい値を取得できるPyObjectとして表されています。しかし、私は配列、xを持っていると思います。Juliaのポインタを再解釈する

+1

'?unsafe_wrap'を試してください。 – tholy

+0

引数 '' pointer :: Ptr {T} ''に何を渡すのですか?私が興味を持っているデータはダブルです。 – user2379888

+1

最初の要素のアドレスを渡します。しかし、私はあなたが実際にポインタを持っているとは思わない、それはいくつかの混乱を引き起こしている。あなたはポインタを含む 'PyObject'を持っています。 'unsafe_wrap'を使うには、メモリブロックのメモリアドレスが必要です。あるいは、PyArrayで 'PyObject'をラップすることもできます。これは、NumPy配列インターフェースとJuliaの抽象配列インフラストラクチャを使ってユリウス配列のように動作させる方法です。 –

答えて

1

ここでは、numpyを使用した簡単な例を示します。デフォルトでは、PyCallはnumpy配列をJuliaの配列に変換しますが、@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オブジェクトを掘り下げなければなりません。

関連する問題