2016-03-06 12 views
5

ジュリアのccall関数を使用してCライブラリとのインターフェイスを確立しようとしています。すべての型とポインタが正しく、以下の関数呼び出しは正解を返すようになりました(簡潔にするためにここでは示していない変数定義と設定)。私は、シンボルとしての機能名を生成し、その後ccallに引数としてそれを使用したい場合はジュリアのccallインターフェイスと記号に関する問題

ccall((:vDSP_convD, libacc), Void, 
      (Ptr{T}, Int64, Ptr{T}, Int64, Ptr{T}, Int64, UInt64, UInt64), 
      x_padded, 1, pointer(K, Ksize), -1, result, 1, Rsize, Ksize) 

しかし、それは失敗します。

fname = symbol(string("vDSP_conv", "D")) 
ccall((fname , libacc), Void, 
      (Ptr{T}, Int64, Ptr{T}, Int64, Ptr{T}, Int64, UInt64, UInt64), 
      x_padded, 1, pointer(K, Ksize), -1, result, 1, Rsize, Ksize) 

エラーは次のとおりです。

ERROR: LoadError: TypeError: conv: in ccall: first argument not a 
pointer or valid constant expression, expected Ptr{T}, 
got Tuple{Symbol,ASCIIString} 

私は、これら2つの命名のバージョンのそれぞれの種類を印刷する場合、私は

julia> println(typeof(:vDSP_convD)) 
     Symbol 
julia> println(typeof(fname)) 
     Symbol 

この作業を取得する方法はありますを取得しますか?私はこの作業をするためにマクロまたは@evalでこれをラップする必要があると推測していますが、上記の機能がなぜ表示されているように機能しないのか不思議です。

ご協力いただければ幸いです。私はそれが仕事を得るために@evalブロックでこれをラップ終わった

EDIT

。しかし、私はまだ上記の構文がうまくいかない理由(なぜそれは時々ポインタを記号として解釈するのか、それ以外の時は解釈しないのか)についてのバックエンドの論理について興味があります

+0

["(:function、" library ")のペアは定数である必要があります]](http://docs.julialang.org/ja/latest/manual/calling-c-and-fortran-code/ #calling-cとfortran-code) – Gnimuc

+1

これを 'const'や' Pair() 'を使って作る方法はありますか? –

答えて

7

ccallは実際には関数ではありません - C ABIを使用してC関数呼び出しに変換される構文形式です。 C関数への呼び出しを出すには、関数のアドレスを静的に解決できる必要があります。 CとJuliaの両方で、可変関数ポインタを使用して関数を呼び出すこともできます。ジュリアでは、通常、dlopendlsymを使用して、このようなポインタを取得する方法がいくつかあります。 ccallがしないものは、定数ではない関数を解決します:これはCでは不可能です(ルックアップテーブルを構築することなく)。 Juliaではevalを使用することで分かりますが、これを行うにはコンパイラのオーバーヘッドがあります。そのため、ccallは自動的にこの処理を行いません。たとえば、誤ってループ内にコンパイラのオーバーヘッドが発生する危険性を避けたい場合などです。

+1

'ccall'の説明に感謝します。私が知りたかったことすべてを説明しています! –

関連する問題