Документация Engee

Интерфейс C

@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 разрешается в текущем процессе. Или @ccall можно также использовать для вызова указателя функции $function_pointer, например возвращенного dlsym.

Каждое argvalue для @ccall преобразуется в соответствующий argtype путем автоматической вставки вызовов unsafe_convert(argtype, cconvert(argtype, argvalue)). (Дополнительные сведения см. в документации по unsafe_convert и cconvert.) В большинстве случаев это просто приводит к вызову convert(argtype, argvalue).

Примеры

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

Здесь вызывается функция стандартной библиотеки С

size_t strlen(char *)

с переменной Julia с именем s. См. также ccall.

Varargs поддерживаются со следующей конвенцией.

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

Точка с запятой используется для отделения обязательных аргументов (которых должно быть не менее одного) от переменного числа аргументов.

Пример использования внешней библиотеки:

# C signature of g_uri_escape_string:
# 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((function_name, library), returntype, (argtype1, ...), argvalue1, ...)
ccall(function_name, returntype, (argtype1, ...), argvalue1, ...)
ccall(function_pointer, returntype, (argtype1, ...), argvalue1, ...)

Вызывает функцию в экспортированной из C общей библиотеке, заданной с помощью кортежа (function_name, library), где каждый компонент является строкой или символом. Можно не задавать библиотеку, а использовать символ или строку function_name, которые разрешаются в текущем процессе. Кроме того, можно также использовать ccall для вызова указателя функции function_pointer, например возвращенного dlsym.

Обратите внимание, что кортеж типа аргумента должен быть литеральным кортежем, а не переменной или выражением со значением кортежа.

Каждое argvalue для ccall преобразуется в соответствующий argtype путем автоматической вставки вызовов unsafe_convert(argtype, cconvert(argtype, argvalue)). (Дополнительные сведения см. в документации по unsafe_convert и cconvert.) В большинстве случаев это просто приводит к вызову convert(argtype, argvalue).

cglobal((symbol, library) [, type=Cvoid])

Получает указатель на глобальную переменную в экспортированной из C общей библиотеке, заданной явным образом как в ccall. Возвращает Ptr{Type}. По умолчанию используется Ptr{Cvoid}, если аргумент Type не указан. Значения могут быть считаны или записаны с помощью unsafe_load или unsafe_store!, соответственно.

@cfunction(callable, ReturnType, (ArgumentTypes...,)) -> Ptr{Cvoid}
@cfunction($callable, ReturnType, (ArgumentTypes...,)) -> CFunction

Создает указатель функции с поддержкой C из функции Julia callable для заданной сигнатуры типа. Для передачи возвращаемого значения в ccall используйте в сигнатуре тип аргумента Ptr{Cvoid}.

Обратите внимание, что кортеж типа аргумента должен быть литеральным кортежем, а не переменной или выражением со значением кортежа (хотя он может содержать выражение с символом), и что эти аргументы будут вычислены в глобальной области во время компиляции (а не отложены до времени выполнения). Добавление $ перед аргументом функции приводит к изменению вместо закрытия среды выполнения для локальной переменной callable (поддерживается не во всех архитектурах).

Примеры

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

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

Обработчик сбора мусора для возвращаемого значения из @cfunction, когда первый аргумент аннотирован $. Как и все обработчики cfunction, он должен быть передан ccall как Ptr{Cvoid}, и будет автоматически преобразован в соответствующий тип на месте вызова.

См. описание @cfunction.

unsafe_convert(T, x)

Преобразует x в аргумент C типа T, где входной x должен быть возвращаемым значением cconvert(T, ...).

В случаях, когда convert необходимо принять объект Julia и преобразовать его в Ptr, эта функция должна использоваться для определения и выполнения такого преобразования.

Следите за тем, чтобы ссылка Julia на x существовала в течение всего времени использования результата этой функции. Соответственно, аргумент x этой функции никогда не должен быть выражением. Он должен быть только именем переменной или ссылкой на поле. Например, x=a.b.c является допустимым вариантом, а x=[a,b,c] — нет.

Префикс unsafe в этой функции указывает на то, что использование результата этой функции после того, как ее аргумент x будет больше не доступен для программы, может привести к неопределенному поведению, включая повреждение или аварийное завершение программы, в более позднее время.

См. также описание cconvert.

cconvert(T,x)

Преобразует x в значение, передаваемое коду C в качестве типа T, обычно путем вызова convert(T, x).

В случаях, когда x невозможно преобразовать в T, cconvert, в отличие от convert, может возвратить объект с типом, отличным от T, который, тем не менее, подходит unsafe_convert для обработки. Результат этой функции должен оставаться допустимым (для сборки мусора) до тех пор, пока результат unsafe_convert больше не понадобится. Это можно использовать для выделения памяти, к которой будет обращаться ccall. Если необходимо выделить несколько объектов, в качестве возвращаемого значения можно использовать кортеж объектов.

Ни convert, ни cconvert не должны принимать объект Julia и преобразовывать его в Ptr.

unsafe_load(p::Ptr{T}, i::Integer=1)

Загрузка значения типа T с адреса i-го элемента (с индексированием от 1), начиная с p. Эквивалентно выражению C p[i-1].

Префикс unsafe в этой функции указывает на то, что проверка, гарантирующая допустимость указателя p, не выполняется. Как и в C, программист отвечает за то, чтобы при вызове этой функции память, на которую указывает ссылка, не освобождалась и не собирался мусор. Неправильное использование может привести к аварийному завершению программы или возвращению «мусорных» ответов. В отличие от C, разыменование области памяти, выделенной в виде другого типа, может быть корректным при условии, что эти типы совместимы.

unsafe_store!(p::Ptr{T}, x, i::Integer=1)

Хранит значение типа T по адресу i-го элемента (с индексированием от 1), начиная с p. Эквивалентно выражению C p[i-1] = x.

Префикс unsafe в этой функции указывает на то, что проверка, гарантирующая допустимость указателя p, не выполняется. Как и в C, программист отвечает за то, чтобы при вызове этой функции память, на которую указывает ссылка, не освобождалась и не собирался мусор. Неправильное использование может привести к аварийному завершению программы. В отличие от C, хранение области памяти, выделенной в виде другого типа, может быть корректным при условии, что эти типы совместимы.

unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)

Копирует элементы N из исходного указателя в конечный без проверки. Размер элемента определяется типом указателей.

Префикс unsafe в этой функции указывает на то, что проверка, гарантирующая допустимость указателей dest и src, не выполняется. Неправильное использование может привести к повреждению или аварийному завершению программы точно так же, как и в C.

unsafe_copyto!(dest::Array, do, src::Array, so, N)

Копирует элементы N из исходного массива в конечный, начиная с линейного индекса so в источнике и do в месте назначения (с индексированием от 1).

Префикс unsafe в этой функции указывает на то, что проверка, гарантирующая, что N находится в границах любого массива, не выполняется. Неправильное использование может привести к повреждению или аварийному завершению программы точно так же, как и в C.

copyto!(dest, do, src, so, N)

Копирует элементы N из коллекции src, начиная с линейного индекса so, в массив dest, начиная с индекса do. Возвращает dest.


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

Копирует все элементы из коллекции src в массив dest, длина которого должна быть больше или равна длине n для src. Первые n элементов dest перезаписываются, остальные не затрагиваются.

См. также описание copy! и copy.

Примеры

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

julia> y = zeros(7);

julia> copyto!(y, x);

julia> y
7-element Vector{Float64}:
 1.0
 0.0
 3.0
 0.0
 5.0
 0.0
 0.0

copyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest

Копирует блок src в диапазоне Rsrc в блок dest в диапазоне Rdest. Размеры двух регионов должны совпадать.

Примеры

julia> A = zeros(5, 5);

julia> B = [1 2; 3 4];

julia> Ainds = CartesianIndices((2:3, 2:3));

julia> Binds = CartesianIndices(B);

julia> copyto!(A, Ainds, B, Binds)
5×5 Matrix{Float64}:
 0.0  0.0  0.0  0.0  0.0
 0.0  1.0  2.0  0.0  0.0
 0.0  3.0  4.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0

copyto!(dest::AbstractMatrix, src::UniformScaling)

Копирует UniformScaling в матрицу.

Совместимость: Julia 1.1

В Julia 1.0 этот метод поддерживал только квадратную матрицу назначения. В Julia 1.1. добавлена поддержка прямоугольной матрицы.

pointer(array [, index])

Получает собственный адрес массива или строки (при необходимости по index заданного расположения).

Эта функция небезопасна. Следите за тем, чтобы ссылка Julia на array существовала в течение всего времени использования указателя. Макрос GC.@preserve следует использовать для защиты аргумента array для сбора мусора в рамках заданного блока кода.

Обычно наиболее предпочтительным вариантом является вызов Ref(array[, index]), так как при этом гарантируется достоверность результата.

unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)

Заключает в объект Array Julia данные, заданные pointer, без создания копии. Тип элементов указателя T определяет тип элементов массива. dims является либо целочисленным (для одномерного массива), либо кортежем измерений массива. own необязательно указывает, должен ли язык Julia принять право собственности на память, вызывая free для указателя, когда на массив уже отсутствует ссылка.

Эта функция помечена как «небезопасная», потому что она завершится сбоем, если pointer не является допустимым адресом памяти для данных запрашиваемой длины. В отличие от unsafe_load и unsafe_store!, программист также отвечает за то, чтобы доступ к базовым данным не осуществлялся через два массива с разными типами элементов, подобно строгому правилу назначения псевдонимов в C.

pointer_from_objref(x)

Получает адрес памяти объекта Julia в виде Ptr. Существование результирующего Ptr не защитит объект от сборки мусора, поэтому необходимо гарантировать, что на объект будет указывать ссылка в течение всего времени использования Ptr.

Эту функцию невозможно вызвать для неизменяемых объектов, поскольку у них отсутствуют стабильные адреса памяти.

См. также описание unsafe_pointer_to_objref.

unsafe_pointer_to_objref(p::Ptr)

Преобразует Ptr в ссылку на объект. Предполагается, что указатель ссылается на допустимый выделяемый в куче объект Julia. Если это не так, начинает действовать неопределенное поведение, поэтому данная функция считается «небезопасной» и должна использоваться с осторожностью.

См. также описание pointer_from_objref.

disable_sigint(f::Function)

Отключает обработчик Ctrl-C во время выполнения функции в текущей задаче для вызова внешнего кода, который может вызывать код Julia, не безопасный для прерываний. Предназначена для вызова с использованием синтаксиса блока do следующим образом:

disable_sigint() do
    # код, небезопасный для прерываний
    ...
end

Не предназначена для рабочих потоков (Threads.threadid() != 1), поскольку InterruptException доставляется только в главный поток. Внешние функции, которые не вызывают код или среду выполнения Julia, автоматически отключают сигнальную разведку во время своего выполнения.

reenable_sigint(f::Function)

Повторно включает обработчик Ctrl-C во время выполнения функции. Временно отменяет эффект действия disable_sigint.

exit_on_sigint(on::Bool)

Устанавливает флаг exit_on_sigint среды выполнения Julia. Если false, Ctrl-C (SIGINT) фиксируется как InterruptException в блоке try. Это поведение по умолчанию в REPL, любой код выполняется с параметрами -e и -E, а скрипт Julia — с параметром -i.

Если true, Ctrl-C не вызывает InterruptException. Для выполнения кода при таком событии требуется atexit. Это поведение по умолчанию для выполнения скрипта Julia без параметра -i.

Совместимость: Julia 1.5

Для функции exit_on_sigint требуется версия Julia не ниже 1.5.

systemerror(sysfunc[, errno::Cint=Libc.errno()])
systemerror(sysfunc, iftrue::Bool)

Вызывает SystemError для errno со строкой с описанием sysfunc, если iftrue имеет значение true.

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

Аналогична systemerror, но применяется для функций API Windows, использующих GetLastError для возвращения ошибки кода вместо задания errno.

Ptr{T}

Адрес памяти, относящийся к данным тип T. Однако нет никакой гарантии, что память действительно является допустимой или что она представляет данные указанного типа.

Ref{T}

Объект, который безопасно ссылается на данные типа T. Этот тип гарантированно указывает на допустимую выделенную в Julia память правильного типа. Базовые данные защищены от освобождения сборщиком мусора до тех пор, пока существует ссылка на Ref.

В Julia объекты Ref разыменовываются (загружаются или хранятся) с помощью [].

Создание Ref со значением x типа T обычно записывается как Ref(x). Кроме того, при создании внутренних указателей на контейнеры (такие как Array или Ptr) функцию можно записать как Ref(a, i) для создания ссылки на i-й элемент a.

Ref{T}() создает ссылку на значение типа T без инициализации. Для битового типа T значением будет то, что в данный момент находится в выделенной памяти. Для небитового типа T ссылка будет неопределенной, и попытка ее разыменования приведет к ошибке «UndefRefError: доступ к неопределенной ссылке».

Чтобы проверить, является ли Ref неопределенной ссылкой, следует использовать isassigned(ref::RefValue). Например, isassigned(Ref{T}()) имеет значение false, если T является небитовым типом. Если T является битовым типом, isassigned(Ref{T}()) всегда будет иметь значение true.

При передаче в качестве аргумента ccall (типа Ptr или Ref) объект Ref будет преобразовывать в собственный указатель данные, на которые он ссылается. Для большинства T или при преобразовании в Ptr{Cvoid} объект будет указателем на данные объекта. Если T имеет тип isbits, это значение можно легко изменять, в противном случае изменение является строго неопределенным поведением.

Как частный случай, задание T = Any приведет к созданию указателя на саму ссылку при преобразовании в Ptr{Any} (jl_value_t const* const*, если T является неизменяемым, в противном случае — jl_value_t *const *). При преобразовании Ptr{Cvoid} будет по-прежнему возвращаться указатель области данных, как и для других T.

Экземпляр C_NULL Ptr можно передать аргументу Ref ccall для его инициализации.

Использование в трансляции

Ref иногда используется в трансляции для того, чтобы значения, на которые указывает ссылка, рассматривались как скалярные.

Примеры

julia> Ref(5)
Base.RefValue{Int64}(5)

julia> isa.(Ref([1,2,3]), [Array, Dict, Int]) # Считает значения, на которые указывает ссылка, скалярными во время трансляции
3-element BitVector:
 1
 0
 0

julia> Ref{Function}()  # Неопределенная ссылка на небитовый тип, функция
Base.RefValue{Function}(#undef)

julia> try
           Ref{Function}()[] # Разыменование неопределенной ссылки приведет к ошибке
       catch e
           println(e)
       end
UndefRefError()

julia> Ref{Int64}()[]; # Ссылка на битовый тип относится к неопределенному значению, если оно не задано

julia> isassigned(Ref{Int64}()) # Ссылка на битовый тип всегда присваивается
true

julia> Ref{Int64}(0)[] == 0 # Явно задать значения для ссылки на битовый тип
true
isassigned(ref::RefValue) -> Bool

Проверяет, связан ли заданный Ref со значением. Результат всегда положителен для Ref объекта битового типа. Возвращает false, если ссылка не определена.

Примеры

julia> ref = Ref{Function}()
Base.RefValue{Function}(#undef)

julia> isassigned(ref)
false

julia> ref[] = (foobar(x) = x)
foobar (generic function with 1 method)

julia> isassigned(ref)
true

julia> isassigned(Ref{Int}())
true
Cchar

Аналогичен собственному типу C char.

Cuchar

Аналогичен собственному типу C unsigned char (UInt8).

Cshort

Аналогичен собственному типу C signed short (Int16).

Cstring

Строка в стиле C, состоящая из Cchar собственного типа подстановочных знаков. Cstring завершаются нулевым символом. О строках в стиле C, состоящих из собственных типов см. в разделе о Cwstring. Дополнительные сведения о взаимодействии строк с C см. в этом руководстве.

Cushort

Аналогичен собственному типу C unsigned short (UInt16).

Cint

Аналогичен собственному типу C signed int (Int32).

Cuint

Аналогичен собственному типу C unsigned int (UInt32).

Clong

Аналогичен собственному типу C signed long.

Culong

Аналогичен собственному типу C unsigned long.

Clonglong

Аналогичен собственному типу C signed long long (Int64).

Culonglong

Аналогичен собственному типу C unsigned long long (UInt64).

Cintmax_t

Аналогичен собственному типу C intmax_t (Int64).

Cuintmax_t

Аналогичен собственному типу C uintmax_t (UInt64).

Csize_t

Аналогичен собственному типу C size_t (UInt).

Cssize_t

Аналогичен собственному типу C ssize_t.

Cptrdiff_t

Аналогичен собственному типу C ptrdiff_t (Int).

Cwchar_t

Аналогичен собственному типу C wchar_t (Int32).

Cwstring

Строка в стиле C, состоящая из Cwchar_t собственного типа подстановочных знаков. Cwstring завершаются нулевым символом.о строках в стиле C, состоящих из собственных типов символов, см. в разделе о Cstring. Дополнительные сведения о взаимодействии строк с C см. в этом руководстве.

Cfloat

Аналогичен собственному типу C float (Float32).

Cdouble

Аналогичен собственному типу C double (Float64).

Интерфейс LLVM

llvmcall(fun_ir::String, returntype, Tuple{argtype1, ...}, argvalue1, ...)
llvmcall((mod_ir::String, entry_fn::String), returntype, Tuple{argtype1, ...}, argvalue1, ...)
llvmcall((mod_bc::Vector{UInt8}, entry_fn::String), returntype, Tuple{argtype1, ...}, argvalue1, ...)

Вызывает код LLVM, приведенный в первом аргументе. Указать этот первый аргумент можно несколькими способами:

  • в виде литеральной строки, представляющей среду IR уровня функции (аналогично блоку define LLVM), с аргументами, доступными в виде последовательных безымянных переменных SSA (%0, %1 и т. д.);

  • в виде двухэлементного кортежа, содержащего строку модуля среды IR и строку, представляющую имя вызываемой функции точки входа;

  • в виде двухэлементного кортежа с модулем, представленным в виде Vector{UInt8} с битовым кодом.

Обратите внимание, что в отличие от ccall, типы аргументов должны быть указаны как тип кортежа, а не кортеж типов. Все типы, а также код LLVM, должны быть указаны как литералы, а не переменные или выражения (для создания этих литералов может потребоваться использовать @eval ).

См. test/llvmcall.jl с примерами использования.