C インターフェース

[email protected] ── マクロ
@ccall library.function_name(argvalue1::argtype1, ...)::returntype
@ccall function_name(argvalue1::argtype1, ...)::returntype
@ccall $function_pointer(argvalue1::argtype1, ...)::returntype

C からエクスポートされた共有ライブラリ library に含まれる関数 function_name を呼び出します。関数は library.function_name という形で指定され、library には文字列定数もしくはリテラルを利用できます。ライブラリ名は省略でき、その場合 function_name は現在のプロセスで解決されます。この他に @ccall には dlsym の返り値などとして取得した関数ポインタを $function_pointer として渡すこともできます。

@ccall に渡す argvalue は自動的に呼ばれる unsafe_convert(argtype, cconvert(argtype, argvalue)) で対応する argtype にそれぞれ変換されます (unsafe_convertcconvert のドキュメントに詳細があります)。多くの場合、この呼び出しは最終的に convert(argtype, argvalue) となります。

@ccall strlen(s::Cstring)::Csize_t

これは C 標準ライブラリに含まれる次の関数を呼び出します:

size_t strlen(char *)

引数には s という名前の Julia 変数が渡されます。ccall のドキュメントも参照してください。

可変長引数は次の記法でサポートされます:

@ccall printf("%s = %d"::Cstring ; "foo"::Cstring, foo::Cint)::Cint

セミコロンが必須の引数と可変長引数を分けます (必須の引数は最低でも一つ必要です)。

外部ライブラリを使う例を示します:

# g_uri_escape_string の C シグネチャ:
# char *g_uri_escape_string(const char *unescaped,
#                           const char *reserved_chars_allowed,
#                           gboolean allow_utf8);
const glib = "libglib-2.0"
@ccall glib.g_uri_escape_string(my_uri::Cstring, ":/"::Cstring, true::Cint)::Cstring

"libglib-2.0".g_uri_escape_string(...) のように、文字列リテラルを関数の名前の前に直接置くこともできます。

ccall ── キーワード
ccall((function_name, library), returntype, (argtype1, ...), argvalue1, ...)
ccall(function_name, returntype, (argtype1, ...), argvalue1, ...)
ccall(function_pointer, returntype, (argtype1, ...), argvalue1, ...)

C からエクスポートされた共有ライブラリに含まれる関数を呼び出します。関数は (function_name, library) という形で指定され、function_namelibrary は文字列またはシンボルとなれます。ライブラリを指定せずにシンボルまたは文字列 function_name だけを渡すこともでき、この場合は現在のプロセスで function_name が解決されます。この他に ccall には dlsym の返り値などとして取得した関数ポインタ function_pointer を渡すこともできます。

引数型のタプルはリテラルのタプルでなければならず、タプルの値を持つ変数や式は使えないことに注意してください。

ccall に渡す argvalue は自動的に呼ばれる unsafe_convert(argtype, cconvert(argtype, argvalue)) で対応する argtype にそれぞれ変換されます (unsafe_convertcconvert のドキュメントに詳細があります)。多くの場合、この呼び出しは最終的に convert(argtype, argvalue) となります。

Core.Intrinsics.cglobal ── 関数
cglobal((symbol, library) [, type=Cvoid])

C からエクスポートされた共有ライブラリに含まれるグローバル変数を指すポインタを取得します。グローバル変数は ccall と同じ記法で指定されます。返り値の型は Ptr{Type} であり、引数 Type が与えられないときのデフォルト値は Ptr{Cvoid} です。値の読み込みと書き込みはそれぞれ unsafe_loadunsafe_store! で行えます。

[email protected] ── マクロ
@cfunction(callable, ReturnType, (ArgumentTypes...,)) -> Ptr{Cvoid}
@cfunction($callable, ReturnType, (ArgumentTypes...,)) -> CFunction

指定された型シグネチャを持つ Julia 関数 callable から、C から呼び出せる関数ポインタを生成します。返り値を ccall に渡すときは引数の型を Ptr{Cvoid} としてください。

引数型のタプルはリテラルのタプルでなければならず、タプルの値を持つ変数や式は使えないことに注意してください (splat 式 ... を含むことはできます)。また引数はグローバルスコープでコンパイル時に評価されます (実行時ではありません)。

関数を表す引数の前に $ を付けると、ローカル変数 callable を包んだ実行時クロージャが作成できます。ただしこの機能は全てのプラットフォームでサポートされるわけではありません。

マニュアルの C と Fortran コードの呼び出しの章も参照してください。

julia> function foo(x::Int, y::Int)
           return x + y
       end

julia> @cfunction(foo, Int, (Int, Int))
Ptr{Cvoid} @0x000000001b82fcd0
Base.CFunction ──
CFunction struct

@cfunction の第一引数に $ を付けて呼び出したときの返り値に対するガベージコレクションハンドルです。他の cfunction ハンドルと同様、ccall が呼び出す関数に引数として CFunction を渡すときは対応する型を Ptr{Cvoid} とするべきであり、そうしておけば CFunction から Ptr{Cvoid} への変換は @cfunction を呼び出した場所で (unsafe_convert を通じて) 自動的に行われます。

@cfunction も参照してください。

Base.unsafe_convert ── 関数
unsafe_convert(T, x)

xT 型の C 引数に変換します。入力 xcconvert(T, ...) の返り値である必要があります。

Julia オブジェクトから Ptr への変換が convert で必要になった場合には、その変換は (convert ではなく) この関数を使って定義されるべきです。

この関数の返り値を使うときは必ず、Julia における x への参照が保持されていることを確認してください。この制限により unsafe_convert の引数に式を渡すことはできず、 変数名あるいはフィールドの参照だけを渡せます。例えば xa.b.c とするのは問題ありませんが、[a,b,c] としてはいけません。

この関数の先頭に付いている unsafe は、この関数の引数に渡した x がプログラムからアクセスできなくなった後にこの関数の返り値を利用すると未定義動作が起こることを意味します。例えばプログラムの破壊や segfault が任意の時点で起こる可能性があります。

cconvert も参照してください。

Base.cconvert ── 関数
cconvert(T,x)

x を C コードに T 型として渡すための値に変換します。変換は通常 convert(T, x) を呼び出すことで行われます。

x を安全に T 型の値に変換できない場合には、convert とは異なり、cconvertT でない (しかし unsafe_convert が扱える) 型のオブジェクトを返すことが許されています。unsafe_convert が返す値が必要とされる間は、この関数の返り値も正当に保つ (GC されないようにする) 必要があります。この関数は ccall が利用するメモリをアロケートするために利用できます。アロケートすべきオブジェクトが複数あるときは、オブジェクトのタプルを返り値とすることも可能です。

convertcconvert はどちらも、受け取った Julia オブジェクトを Ptr に変換してはいけません。

Base.unsafe_load ── 関数
unsafe_load(p::Ptr{T}, i::Integer=1)

p から (1 始まりで) 数えて i 番目の要素のアドレスから T 型の値を一つ読みます。これは C の式 p[i-1] と等価です。

この関数の先頭に付いている unsafe は、ポインタ p が正当である検査が一切行われないことを意味します。C と同様に、間違ったポインタを使うとプログラムが segfault したり、滅茶苦茶な値が返ったりします。

Base.unsafe_store! ── 関数
unsafe_store!(p::Ptr{T}, x, i::Integer=1)

p から (1 始まりで) 数えて i 番目の要素のアドレスへ T 型の値を一つ書き込みます。これは C の式 p[i-1] = x と等価です。

この関数の先頭に付いている unsafe は、ポインタ p が正当である検査が一切行われないことを意味します。C と同様に、間違ったポインタを使うとプログラムの破壊や segfault が起こる可能性があります。

Base.unsafe_copyto! ── メソッド
unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)

ソースのポインタ src から目的地のポインタ destN 個の要素をコピーします。アドレスが正当である検査は行われません。要素のサイズはポインタの型から決定されます。

この関数の先頭に付いている unsafe は、ポインタ destsrc が正当である検査が一切行われないことを意味します。C と同様に、間違ったポインタを使うとプログラムの破壊や segfault が起こる可能性があります。

Base.unsafe_copyto! ── メソッド
unsafe_copyto!(dest::Array, doffs, src::Array, soffs, N)

ソースの配列 src から目的地の配列 destN 個の要素をコピーします。コピーは srcsoffs 番目の要素および destdoffs 番目の要素から始まります (いずれも添え字は 1 始まり)。

この関数の先頭に付いている unsafe は、N 番目の要素が両方の配列で境界内であることの確認が一切行われないことを意味します。C と同様に、間違ったポインタを使うとプログラムの破壊や segfault が起こる可能性があります。

Base.copyto! ── 関数
copyto!(dest::AbstractMatrix, src::UniformScaling)

UniformScaling を行列にコピーします。

Julia 1.1

Julia 1.0 の copyto! は正方行列に対するコピーだけをサポートします。長方行列に対するサポートは Julia 1.1 で追加されました。

copyto!(dest, doffs, src, soffs, N)

コレクション src の第 soffs 要素の位置から、配列 dest の第 doffs 要素の位置に N 個の要素をコピーします。

copyto!(dest::AbstractArray, src) -> dest

コレクション src の全ての要素を配列 dest にコピーします。dest の長さは src の長さ n 以上である必要があります。dest の最初の n 要素が上書きされ、他の要素はそのままとなります。

julia> x = [1., 0., 3., 0., 5.];

julia> y = zeros(7);

julia> copyto!(y, x);

julia> y
7-element Array{Float64,1}:
 1.0
 0.0
 3.0
 0.0
 5.0
 0.0
 0.0
copyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest

区間 Rsrc に含まれる src のブロックを、区間 Rdest に含まれる dest のブロックにコピーします。二つの領域のサイズは一致する必要があります。

Base.pointer ── 関数
pointer(array [, index])

配列または文字列のネイティブアドレスを取得します。省略可能引数 index を指定すると、その位置のアドレスが返ります。

この関数は “unsafe” です。この関数が返すポインタを使うときは、Julia に array を指す参照が存在することを確認してから使ってください。引数 array を特定のコードブロック中でガベージコレクトしないようにするには [email protected] マクロを使うべきです。

一般に、引数の正当性を確認する Ref(array[, index]) がこの関数よりも推奨されます。

Base.unsafe_wrap ── メソッド
unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)

pointer が指すアドレスにあるデータを包んで Julia の Array オブジェクトを作成します。データのコピーは行われません。ポインタの要素型 T が配列の要素型となります。作成するのが一次元配列とき dims は大きさを表す整数で、それ以外のとき dims は配列の次元を指定するタプルです。省略可能なキーワード引数 own は Julia がメモリの所有権を取得するかを制御し、true にすると作成される配列が参照されなくなったときにポインタに対して free が Julia から呼ばれるようになります。

この関数に “unsafe” が付いているのは、pointer が要求した長さを持つデータを指す正当なメモリアドレスでないときクラッシュするためです。

Base.pointer_from_objref ── 関数
pointer_from_objref(x)

Julia オブジェクトのメモリアドレスを Ptr として取得します。返り値の Ptr が存在してもオブジェクト x がガベージコレクトから守られることはないので、返り値の Ptr が使われるときは必ず x が何らかの形で参照されていることを保証する必要があります。

不変オブジェクトは安定なメモリアドレスを持たないため、この関数を不変オブジェクトに対して呼び出すことはできません。

unsafe_pointer_to_objref も参照してください。

unsafe_pointer_to_objref(p::Ptr)

Ptr をオブジェクトの参照に変換します。ポインタ p がヒープにアロケートされた正当な Julia オブジェクトを指すことが仮定されます。この仮定が破られると未定義動作が起こるので、この関数は注意して使わなければならない “unsafe” な関数です。

pointer_from_objref も参照してください。

Base.disable_sigint ── 関数
disable_sigint(f::Function)

現在のタスクで Ctrl-C ハンドラを無効化した状態で関数を実行します。Julia コードを呼び出す可能性のある割り込み安全でない外部コードを呼び出すときに使われます。do ブロックを使って次のように呼ばれることが意図されています:

disable_sigint() do
    # 割り込み安全でないコード
    ...
end

InterruptException はマスタースレッドにだけ届けられるので、この関数はワーカースレッド (Threads.threadid() != 1 のスレッド) では必要ありません。また Julia コードや Julia ランタイムを呼ばない外部関数の実行中は sigint が自動的に無効化されます。

Base.reenable_sigint ── 関数
reenable_sigint(f::Function)

Ctrl-C ハンドラを再度有効化した状態で関数を実行します。disable_sigint の効果を一時的に打ち消します。

Base.exit_on_sigint ── 関数
exit_on_sigint(on::Bool)

Julia ランタイムの exit_on_sigint フラグを設定します。false に設定すると、Ctrl-C (SIGINT) を try ブロックの中で InterruptException として捕捉できるようになります。これは REPL におけるデフォルトの振る舞いであり、-e-E で実行する Julia コードや -i オプションで実行される Julia スクリプトでも同様です。

exit_on_sigint フラグを true に設定すると、Ctrl-C は InterruptException を送出しません。そういったイベントでコードを実行するには atexit を使ってください。この振る舞いは -i オプションを付けずに Julia スクリプトを実行するときのデフォルトです。

Julia 1.5

exit_on_sigint 関数は Julia 1.5 以降でサポートされます。

Base.systemerror ── 関数
systemerror(sysfunc[, errno::Cint=Libc.errno()])
systemerror(sysfunc, iftrue::Bool)

説明文 sysfunc とエラー番号 errno を持った SystemError を送出します。二つ目の形式では、iftruetrue のときに限ってエラーを送出します。

Base.windowserror ── 関数
windowserror(sysfunc[, code::UInt32=Libc.GetLastError()])
windowserror(sysfunc, iftrue::Bool)

systemerror と同様ですが、エラーコードを (errno ではなく) GetLastError を通して返す Windows API 関数に対するエラーを送出します。

Core.Ptr ──
Ptr{T}

T 型のデータを指すメモリアドレスです。ただし、この型の値が指すメモリが正当であること、およびそこにあるデータが本当に T 型のデータであることの保証はありません。

Core.Ref ──
Ref{T}

T 型のデータを安全に参照するオブジェクトです。この型の値は Julia がアロケートした正当なメモリにある正しい型のデータを指すことが保証されています。Ref がどこかで参照されている限り、ガベージコレクタはその内部データを解放しません。

Julia では、Ref オブジェクトのデリファレンス (読み込みと書き込み) を [] で行います。

T 型の値 x に対する Ref の作成はよく Ref(x) と書かれます。これ以外にも、ArrayPtr といったコンテナの内部要素を指すポインタを作るときは、a の第 i 要素に対する参照の作成を Ref(a, i) と書けます。

ccall の引数に (Ptr 型または Ref 型として) 渡されたRef オブジェクトは、参照するデータを指すネイティブポインタへと変換されます。

Julia に不当な Ref (NULL) は存在しません。ただし C_NULL を保持する Ptr インスタンスを ccall に対する Ref 型の引数に渡すことはできます。

ブロードキャストでの利用

Ref は参照される値をブロードキャストでスカラーとして扱うために使われることがあります:

julia> isa.(Ref([1,2,3]), [Array, Dict, Int])
3-element BitArray{1}:
 1
 0
 0
Base.Cchar ──
Cchar

ネイティブな C 型 char 型と等価です。

Base.Cuchar ──
Cuchar

ネイティブな C 型 unsigned char と等価です (つまり UInt8 です)。

Base.Cshort ──
Cshort

ネイティブな C 型 signed short と等価です (つまり Int16 です)。

Base.Cstring ──
Cstring

ネイティブの文字型 Cchar から構成される C スタイルの文字列です。Cstring はヌル終端を持ちます。ネイティブのワイド文字列型から構成される C スタイルの文字列については Cwstring を見てください。C との文字列のやり取りについて詳しくはマニュアルの対応表を参照してください。

Base.Cushort ──
Cushort

ネイティブな C 型 unsigned short と等価です (つまり UInt16 です)。

Base.Cint ──
Cint

ネイティブな C 型 signed int と等価です (つまり Int32 です)。

Base.Cuint ──
Cuint

ネイティブな C 型 unsigned int と等価です (つまり UInt32 です)。

Base.Clong ──
Clong

ネイティブな C 型 signed long と等価です。

Base.Culong ──
Culong

ネイティブな C 型 unsigned long と等価です。

Base.Clonglong ──
Clonglong

ネイティブな C 型 signed long long と等価です (つまり Int64 です)。

Base.Culonglong ──
Culonglong

ネイティブな C 型 unsigned long long と等価です (つまり UInt64 です)。

Base.Cintmax_t ──
Cintmax_t

ネイティブな C 型 intmax_t と等価です (つまり Int64 です)。

Base.Cuintmax_t ──
Cuintmax_t

ネイティブな C 型 uintmax_t と等価です (つまり UInt64 です)。

Base.Csize_t ──
Csize_t

ネイティブな C 型 size_t と等価です (つまり UInt です)。

Base.Cssize_t ──
Cssize_t

ネイティブな C 型 ssize_t と等価です。

Base.Cptrdiff_t ──
Cptrdiff_t

ネイティブな C 型 ptrdiff_t と等価です (つまり Int です)。

Base.Cwchar_t ──
Cwchar_t

ネイティブな C 型 wchar_t と等価です (つまり Int32 です)。

Base.Cwstring ──
Cwstring

ネイティブなワイド文字型 Cwchar_t から構成される C スタイルの文字列です。Cwstring はヌル終端を持ちます。ネイティブな文字型から構成される C スタイルの文字列については Cstring を参照してください。C との文字列のやり取りについて詳しくはマニュアルの対応表を参照してください。

Base.Cfloat ──
Cfloat

ネイティブな C 型 float と等価です (つまり Float32 です)。

Base.Cdouble ──
Cdouble

ネイティブな C 型 double と等価です (つまり Float64 です)。

LLVM インターフェース

Core.Intrinsics.llvmcall ── 関数
llvmcall(IR::String,
         ReturnType,
         (ArgumentType1, ...),
         ArgumentValue1, ...)
llvmcall((declarations::String, IR::String),
         ReturnType,
         (ArgumentType1, ...),
         ArgumentValue1, ...)

第一引数に渡される LLVM IR 文字列を実行します。LLVM 関数の define ブロックと同様に、引数は名前を持たない連続した SSA 変数 (%0, %1, ...) として利用可能になります。

省略可能な文字列 declarations には、引数として渡す IR 文字列を llvm がコンパイルするときに必要になる外部関数の宣言を指定します。複数の宣言を指定するには改行で区切ります。

引数型のタプルはリテラルのタプルでなければならず、タプルの値を持つ変数や式は使えないことに注意してください。

llvmcall に渡す ArgumentValue は自動的に呼ばれる unsafe_convert(ArgumentType, cconvert(ArgumentType, ArgumentValue)) で対応する ArgumentType に変換されます (詳細は unsafe_convertcconvert のドキュメントを参照してください)。多くの場合、この変換は convert(ArgumentType, ArgumentValue) を呼び出すだけです。

利用例は /test/llvmcall.jl を見てください。