2016-10-19 9 views
9

私はもともとこの疑問の私の定式化をひどく悩ましました(これは真剣にC++コードを書いてから1年以上経ちました。もう一度お試しください。JuliaのC voidポインタを宣言する適切な方法

いくつかのCコードは、次の

void* p; 
create_new_thing(&p); //p is now a new thing 
do_stuff_to_thing(p); //something happened to p 

私の質問は、ジュリアにオブジェクトpを作成する方法であるように、あなたが何かをすることを期待して書かれています。今私は、私は同じコードを信じているが、pp = Array(Ptr{Void}, 1)も働く代わりとして宣言され、答えはさらに

p = Ref{Ptr{Void}}() 
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p) 
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p) 

であると信じます。

私は、ジュリアのRefPtrの間の全体的な区別が非常に混乱していることがわかりました。なぜなら、私は追跡できない方法でお互いに変換されているからです。

+0

詳細は以下のとおりです。 '無効* pで、'、 'p'は "新しいこと"(オブジェクト)です。 'create_new_thing(&p);')は、関数が値を割り当てていることを許可します。Juliaとの幸運 – chux

+0

私がオブジェクトという言葉を使わなかった理由は、私が非常に具体的であることを懸念していたからです。 –

+0

Cでは、_object_は "データ保存領域..."の_general_という用語で、その内容は文字、整数、浮動小数点、ポインタ、配列、構造体、共用体などの値を表すことができます。関数を除いて指すことのできるものについて – chux

答えて

9

あなたのコードはとよく見えます。です。しかし、注意してください!どんな小さな誤差は、セグメンテーションフォールトを引き起こす可能性がありますが、ここに持っているもののよう:

p = Ref{Ptr{Void}}() 
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p) 
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p) 
             # error here^

それを行うための正しい方法はpp[]を使用するかを理解するための最も簡単な方法がある

p = Ref{Ptr{Void}}() 
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p) 
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p[]) 
              # fixed^

です対応するCコードを考える。 Cのオブジェクトが行うようにCで、私たちが書く

void *p; 
create_new_thing(&p) 
do_stuff_to_thing(p) 

ジュリアオブジェクトは、ファーストクラスのメモリアドレスを持っていないので、我々はメモリアドレスを取得するにはジュリアにp = Ref{Ptr{Void}}()を使用する必要があります。このオブジェクトはrefとして、&pのように振る舞います。つまり、オブジェクト自体を取得することを意味します。p Cでは、Juliaにp[]を使用する必要があります。

だから、ジュリアの等価は

p = Ref{Ptr{Void}}()     # this p corresponds to &p in C 
ccall(:create_new_thing, ..., p)  # like &p 
ccall(:do_stuff_to_thing, ..., p[]) # like *(&p); that is, like p 
+1

最初の 'ccall'シグネチャは' Ptr {Ptr {Void}} 'の代わりに' Ref {Ptr {Void}} ' /docs.julialang.org/en/release-0.5/manual/calling-c-and-fortran-code/#passing-pointers-for-modifying-inputs –

+1

@SimonByrne私の理解から、彼らはこの場合には全く同じですが、私はOPのコードをそのまま保存しました。 –

+1

私はそれらが現時点では同等だと思いますが、マニュアルでは可変ポインタに対して 'Ref'を推奨しています。 –

関連する問題