Интерфейс C
#
Base.@ccall
— Macro
@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
— Keyword
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)
.
#
Core.Intrinsics.cglobal
— Function
cglobal((symbol, library) [, type=Cvoid])
Получает указатель на глобальную переменную в экспортированной из C общей библиотеке, заданной явным образом как в ccall
. Возвращает Ptr{Type}
. По умолчанию используется Ptr{Cvoid}
, если аргумент Type
не указан. Значения могут быть считаны или записаны с помощью unsafe_load
или unsafe_store!
, соответственно.
#
Base.@cfunction
— Macro
@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
#
Base.CFunction
— Type
CFunction struct
Обработчик сбора мусора для возвращаемого значения из @cfunction
, когда первый аргумент аннотирован $. Как и все обработчики cfunction
, он должен быть передан ccall
как Ptr{Cvoid}
, и будет автоматически преобразован в соответствующий тип на месте вызова.
См. описание @cfunction
.
#
Base.unsafe_convert
— Function
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
.
#
Base.cconvert
— Function
cconvert(T,x)
Преобразует x
в значение, передаваемое коду C в качестве типа T
, обычно путем вызова convert(T, x)
.
В случаях, когда x
невозможно преобразовать в T
, cconvert
, в отличие от convert
, может возвратить объект с типом, отличным от T
, который, тем не менее, подходит unsafe_convert
для обработки. Результат этой функции должен оставаться допустимым (для сборки мусора) до тех пор, пока результат unsafe_convert
больше не понадобится. Это можно использовать для выделения памяти, к которой будет обращаться ccall
. Если необходимо выделить несколько объектов, в качестве возвращаемого значения можно использовать кортеж объектов.
Ни convert
, ни cconvert
не должны принимать объект Julia и преобразовывать его в Ptr
.
#
Base.unsafe_load
— Function
unsafe_load(p::Ptr{T}, i::Integer=1)
Загрузка значения типа T
с адреса i
-го элемента (с индексированием от 1), начиная с p
. Эквивалентно выражению C p[i-1]
.
Префикс unsafe
в этой функции указывает на то, что проверка, гарантирующая допустимость указателя p
, не выполняется. Как и в C, программист отвечает за то, чтобы при вызове этой функции память, на которую указывает ссылка, не освобождалась и не собирался мусор. Неправильное использование может привести к аварийному завершению программы или возвращению «мусорных» ответов. В отличие от C, разыменование области памяти, выделенной в виде другого типа, может быть корректным при условии, что эти типы совместимы.
#
Base.unsafe_store!
— Function
unsafe_store!(p::Ptr{T}, x, i::Integer=1)
Хранит значение типа T
по адресу i
-го элемента (с индексированием от 1), начиная с p
. Эквивалентно выражению C p[i-1] = x
.
Префикс unsafe
в этой функции указывает на то, что проверка, гарантирующая допустимость указателя p
, не выполняется. Как и в C, программист отвечает за то, чтобы при вызове этой функции память, на которую указывает ссылка, не освобождалась и не собирался мусор. Неправильное использование может привести к аварийному завершению программы. В отличие от C, хранение области памяти, выделенной в виде другого типа, может быть корректным при условии, что эти типы совместимы.
#
Base.unsafe_copyto!
— Method
unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)
Копирует элементы N
из исходного указателя в конечный без проверки. Размер элемента определяется типом указателей.
Префикс unsafe
в этой функции указывает на то, что проверка, гарантирующая допустимость указателей dest
и src
, не выполняется. Неправильное использование может привести к повреждению или аварийному завершению программы точно так же, как и в C.
#
Base.unsafe_copyto!
— Method
unsafe_copyto!(dest::Array, do, src::Array, so, N)
Копирует элементы N
из исходного массива в конечный, начиная с линейного индекса so
в источнике и do
в месте назначения (с индексированием от 1).
Префикс unsafe
в этой функции указывает на то, что проверка, гарантирующая, что N находится в границах любого массива, не выполняется. Неправильное использование может привести к повреждению или аварийному завершению программы точно так же, как и в C.
#
Base.copyto!
— Function
copyto!(dest, do, src, so, N)
Копирует элементы N
из коллекции src
, начиная с линейного индекса so
, в массив dest
, начиная с индекса do
. Возвращает dest
.
copyto!(dest::AbstractArray, src) -> dest
Копирует все элементы из коллекции src
в массив dest
, длина которого должна быть больше или равна длине n
для src
. Первые n
элементов dest
перезаписываются, остальные не затрагиваются.
Примеры
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. добавлена поддержка прямоугольной матрицы. |
#
Base.pointer
— Function
pointer(array [, index])
Получает собственный адрес массива или строки (при необходимости по index
заданного расположения).
Эта функция небезопасна. Следите за тем, чтобы ссылка Julia на array
существовала в течение всего времени использования указателя. Макрос GC.@preserve
следует использовать для защиты аргумента array
для сбора мусора в рамках заданного блока кода.
Обычно наиболее предпочтительным вариантом является вызов Ref(array[, index])
, так как при этом гарантируется достоверность результата.
#
Base.unsafe_wrap
— Method
unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)
Заключает в объект Array
Julia данные, заданные pointer
, без создания копии. Тип элементов указателя T
определяет тип элементов массива. dims
является либо целочисленным (для одномерного массива), либо кортежем измерений массива. own
необязательно указывает, должен ли язык Julia принять право собственности на память, вызывая free
для указателя, когда на массив уже отсутствует ссылка.
Эта функция помечена как «небезопасная», потому что она завершится сбоем, если pointer
не является допустимым адресом памяти для данных запрашиваемой длины. В отличие от unsafe_load
и unsafe_store!
, программист также отвечает за то, чтобы доступ к базовым данным не осуществлялся через два массива с разными типами элементов, подобно строгому правилу назначения псевдонимов в C.
#
Base.pointer_from_objref
— Function
pointer_from_objref(x)
Получает адрес памяти объекта Julia в виде Ptr
. Существование результирующего Ptr
не защитит объект от сборки мусора, поэтому необходимо гарантировать, что на объект будет указывать ссылка в течение всего времени использования Ptr
.
Эту функцию невозможно вызвать для неизменяемых объектов, поскольку у них отсутствуют стабильные адреса памяти.
См. также описание unsafe_pointer_to_objref
.
#
Base.unsafe_pointer_to_objref
— Function
unsafe_pointer_to_objref(p::Ptr)
Преобразует Ptr
в ссылку на объект. Предполагается, что указатель ссылается на допустимый выделяемый в куче объект Julia. Если это не так, начинает действовать неопределенное поведение, поэтому данная функция считается «небезопасной» и должна использоваться с осторожностью.
См. также описание pointer_from_objref
.
#
Base.disable_sigint
— Function
disable_sigint(f::Function)
Отключает обработчик Ctrl-C во время выполнения функции в текущей задаче для вызова внешнего кода, который может вызывать код Julia, не безопасный для прерываний. Предназначена для вызова с использованием синтаксиса блока do
следующим образом:
disable_sigint() do # код, небезопасный для прерываний ... end
Не предназначена для рабочих потоков (Threads.threadid() != 1
), поскольку InterruptException
доставляется только в главный поток. Внешние функции, которые не вызывают код или среду выполнения Julia, автоматически отключают сигнальную разведку во время своего выполнения.
#
Base.reenable_sigint
— Function
reenable_sigint(f::Function)
Повторно включает обработчик Ctrl-C во время выполнения функции. Временно отменяет эффект действия disable_sigint
.
#
Base.exit_on_sigint
— Function
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
Для функции |
#
Base.systemerror
— Function
systemerror(sysfunc[, errno::Cint=Libc.errno()])
systemerror(sysfunc, iftrue::Bool)
Вызывает SystemError
для errno
со строкой с описанием sysfunc
, если iftrue
имеет значение true
.
#
Base.windowserror
— Function
windowserror(sysfunc[, code::UInt32=Libc.GetLastError()])
windowserror(sysfunc, iftrue::Bool)
Аналогична systemerror
, но применяется для функций API Windows, использующих GetLastError
для возвращения ошибки кода вместо задания errno
.
#
Core.Ptr
— Type
Ptr{T}
Адрес памяти, относящийся к данным тип T
. Однако нет никакой гарантии, что память действительно является допустимой или что она представляет данные указанного типа.
#
Core.Ref
— Type
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
#
Base.isassigned
— Method
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
#
Base.Cstring
— Type
Cstring
Строка в стиле C, состоящая из Cchar
собственного типа подстановочных знаков. Cstring
завершаются нулевым символом. О строках в стиле C, состоящих из собственных типов см. в разделе о Cwstring
. Дополнительные сведения о взаимодействии строк с C см. в этом руководстве.
#
Base.Cwstring
— Type
Cwstring
Строка в стиле C, состоящая из Cwchar_t
собственного типа подстановочных знаков. Cwstring
завершаются нулевым символом.о строках в стиле C, состоящих из собственных типов символов, см. в разделе о Cstring
. Дополнительные сведения о взаимодействии строк с C см. в этом руководстве.
Интерфейс LLVM
#
Core.Intrinsics.llvmcall
— Function
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
с примерами использования.