C接口
# '基。@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’返回。
通过自动插入对`unsafe_convert(argtype,cconvert(argtype,argvalue))的调用,将
@ccall`的每个`argvalue`转换为相应的`argtype`。 (有关更多信息,请参阅 '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 для 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'。
请注意,参数类型的元组必须是字面元组,而不是具有元组值的变量或表达式。
通过自动插入对`unsafe_convert(argtype,cconvert(argtype,argvalue))的调用,将`ccall`的每个`argvalue`转换为相应的’argtype
。 (有关更多信息,请参阅 'unsafe_convert'和 'cconvert'。)在大多数情况下,这只是导致调用`convert(argtype,argvalue)'。
# ’核心。内在。cglobal'*-Function
cglobal((symbol, library) [, type=Cvoid])
获取指向从C导出的共享库中的全局变量的指针,显式指定为 'ccall'。 返回`Ptr{Type}. 默认情况下,使用'Ptr'。{Cvoid}'如果没有指定’Type’参数。 值可以分别使用读取或写入 '不安全负荷'或 'unsafe_store!
.
# '基。@cfunction'-Macro
@cfunction(callable, ReturnType, (ArgumentTypes...,)) -> Ptr{Cvoid}
@cfunction($callable, ReturnType, (ArgumentTypes...,)) -> CFunction
为指定的类型签名从Julia`callable`函数创建一个启用C的函数指针。 要将返回值传递给’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'—Type
CFunction struct
当第一个参数用$注释时,来自`@cfunction`的返回值的垃圾收集描述符。 像所有`cfunction`描述符一样,它必须作为`Ptr传递给`ccall`{Cvoid}`,并在呼叫位置自动转换为适当的类型。
请参阅说明 '@cfunction'。
# '基。unsafe_convert'-Function
unsafe_convert(T, x)
将`x’转换为`T’类型的c参数,其中输入’x’应该是返回值'cconvert(T,...)`.
在以下情况下 'convert'有必要采取Julia对象并将其转换为’Ptr',这个函数应该用于定义和执行这样的转换。
确保Julia对`x`的引用在使用此函数的结果的整个持续时间内存在。 因此,这个函数的参数’x’不应该是一个表达式。 它应该只是变量名称或字段引用。 例如’x=a.b.c’是一个有效的选项,但`x=[a,b,c]`不是。
此函数中的前缀"不安全"表示在其参数"x"对程序不再可用后使用此函数的结果可能导致未定义的行为,包括程序损坏或稍后崩溃。
另请参阅说明 'cconvert'。
# '基。cconvert'-Function
cconvert(T,x)
将`x`转换为作为类型`T’传递给C代码的值,通常通过调用`convert(T,x)'。
在`x`不能安全地转换为`T`的情况下,'cconvert',不像 'convert',可以返回除`T’之外的类型的对象,尽管如此,它适合由函数处理 'unsafe_convert'。 此函数的结果应该保持有效(对于垃圾回收),只要结果 'unsafe_convert'将不再需要。 这可用于分配将被`ccall’访问的内存。 如果需要选择多个对象,可以使用对象元组作为返回值。
'Convert’和’cconvert’都不应该采用Julia对象并将其转换为’Ptr'。
# '基。unsafe_load'-Function
unsafe_load(p::Ptr{T}, i::Integer=1)
unsafe_load(p::Ptr{T}, order::Symbol)
unsafe_load(p::Ptr{T}, i::Integer, order::Symbol)
从第i个元素的地址(从1开始索引)加载一个类型为"T"的值,从"p"开始。 它相当于表达式C’p[i-1]'。 如果需要,可以提供原子存储器排序。
此函数中的前缀"unsafe"表示不执行确保指针"p"有效性的检查。 与在C中一样,程序员负责确保在调用此函数时,引用的内存不会被释放,垃圾也不会被收集。 使用不当可能会导致程序崩溃或返回"垃圾"响应。 与在C中不同,取消引用分配为不同类型的内存区域可以是正确的,前提是这些类型是兼容的。
兼容性:Julia1.10
"秩序"论点首先在Julia1.10中实现。 |
另请参阅说明 '原子'。
# '基。unsafe_store!`-Function</no-翻译>
unsafe_store!(p::Ptr{T}, x, i::Integer=1)
unsafe_store!(p::Ptr{T}, x, order::Symbol)
unsafe_store!(p::Ptr{T}, x, i::Integer, order::Symbol)
在第i个元素的地址(从1开始索引)存储类型为"T"的值,从"p"开始。 它相当于表达式C’p[i-1]=x`。 如果需要,可以提供原子存储器排序。
此函数中的前缀"unsafe"表示不执行确保指针"p"有效性的检查。 与在C中一样,程序员负责确保在调用此函数时,引用的内存不会被释放,垃圾也不会被收集。 使用不当可能会导致程序崩溃。 与在C中不同,存储分配为不同类型的内存区域可以是正确的,前提是这些类型是兼容的。
兼容性:Julia1.10
"秩序"论点首先在Julia1.10中实现。 |
另请参阅说明 '原子'。
# '基。unsafe_modify!`-Function</no-翻译>
unsafe_modify!(p::Ptr{T}, op, x, [order::Symbol]) -> Pair
获取和指定内存地址的操作在应用’op’函数后以原子方式执行。 如果这样的特征(例如,原子增量)由硬件支持,则可以使用适当的硬件指令来优化操作。 否则,执行会发生这样的情况:
y = unsafe_load(p) z = op(y, x) unsafe_store!(p, z) return y => z
此函数中的前缀"unsafe"表示不执行确保指针"p"有效性的检查。 与在C中一样,程序员负责确保在调用此函数时,引用的内存不会被释放,垃圾也不会被收集。 使用不当可能会导致程序崩溃。
兼容性:Julia1.10
此功能需要Julia至少1.10的版本。 |
另请参阅说明 'modifyproperty!`, '原子'
# '基。unsafe_replace!`-Function</no-翻译>
unsafe_replace!(p::Ptr{T}, expected, desired,
[success_order::Symbol[, fail_order::Symbol=success_order]]) -> (; old, success::Bool)
获取内存地址并有条件地为其分配指定值的操作是原子地执行的。 如果硬件支持此功能,则可以使用适当的硬件指令优化操作。 否则,执行会发生这样的情况:
y = unsafe_load(p, fail_order) ok = y === expected if ok unsafe_store!(p, desired, success_order) end return (; old = y, success = ok)
此函数中的前缀"unsafe"表示不执行确保指针"p"有效性的检查。 与在C中一样,程序员负责确保在调用此函数时,引用的内存不会被释放,垃圾也不会被收集。 使用不当可能会导致程序崩溃。
兼容性:Julia1.10
此功能需要Julia至少1.10的版本。 |
另请参阅说明 'replaceproperty!`, '原子'
# '基。unsafe_swap!`-Function</no-翻译>
unsafe_swap!(p::Ptr{T}, x, [order::Symbol])
同时获取和指定内存地址的操作以原子方式执行。 如果硬件支持此功能,则可以使用适当的硬件指令优化操作。 否则,执行会发生这样的情况:
y = unsafe_load(p) unsafe_store!(p, x) return y
此函数中的前缀"unsafe"表示不执行确保指针"p"有效性的检查。 与在C中一样,程序员负责确保在调用此函数时,引用的内存不会被释放,垃圾也不会被收集。 使用不当可能会导致程序崩溃。
兼容性:Julia1.10
此功能需要Julia至少1.10的版本。 |
另请参阅说明 'swapproperty!`, '原子'
# '基。unsafe_copyto!`-Method</no-翻译>
unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)
将`N`元素从源指针复制到目标而不进行检查。 元素的大小由指针的类型决定。
此函数中的前缀"unsafe"表示不执行确保"dest"和"src"指针有效性的验证。 使用不当会导致程序损坏或崩溃,就像在C中一样。
# '基。unsafe_copyto!`-Method</no-翻译>
unsafe_copyto!(dest::Array, do, src::Array, so, N)
将`N`元素从源数组复制到目标,从源数组的线性索引`so`开始,目标数组的线性索引`do’开始(从1开始索引)。
此函数中的前缀"unsafe"表示不执行确保N在任何数组边界内的检查。 使用不当会导致程序损坏或崩溃,就像在C中一样。
# '基。收到!`-Function</no-翻译>
copyto!(B::AbstractMatrix, ir_dest::AbstractUnitRange, jr_dest::AbstractUnitRange,
tM::AbstractChar,
M::AbstractVecOrMat, ir_src::AbstractUnitRange, jr_src::AbstractUnitRange) -> B
有效地将矩阵`M’的元素复制到’B`,考虑到符号参数’tM’如下:
'tM` | 目的地 | 一个来源 |
---|---|---|
|
'B[ir_dest,jr_dest]` |
'M[ir_src,jr_src]` |
|
'B[ir_dest,jr_dest]` |
'转置(M)[ir_src,jr_src]` |
|
'B[ir_dest,jr_dest]` |
'adjoint(M)[ir_src,jr_src]` |
元素’b[ir_dest,jr_dest]'被复盖。 此外,索引范围参数必须满足条件`length(ir_dest)==length(ir_src)和`length(jr_dest)==length(jr_src)
。
另请参阅说明 'copy_transpose!和 'copy_adjoint!.
copyto!(dest::AbstractMatrix, src::UniformScaling)
副本 `UniformScaling'到矩阵。
兼容性:Julia1.1
在Julia1.0中,此方法仅支持正方形目标矩阵。 在朱莉娅1.1。 增加了矩形矩阵支持。 |
copyto!(dest, do, src, so, N)
将从线性索引`so`开始的`src`集合中的`N’元素复制到从索引`do`开始的`dest’数组中。 返回"dest"。
copyto!(dest::AbstractArray, src) -> dest
将`src`集合中的所有元素复制到`dest`数组中,其长度必须大于或等于`src`的’n’长度。 `Dest`的前`n`个元素被复盖,其余的不受影响。
如果任何修改的参数被放置在与任何其他参数相同的内存区域中,则行为可能是意外的。 |
例子
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
将`rsrc`范围内的`src`块复制到`Rdest`范围内的`dest’块。 两个区域的大小必须匹配。
例子
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
# '基。指针'-Function
pointer(array [, index])
获取数组或字符串的自己的地址(如果需要,通过指定位置的"索引")。
此功能不安全。 确保Julia对`array`的引用在指针使用的整个时间内都存在。 宏 'GC。@preserve'应该用于保护给定代码块内垃圾回收的`array’参数。
通常最优选的选择是调用 'Ref(array[,index]’,因为这保证了结果的有效性。
# '基。unsafe_wrap'-Method
unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)
将数据包含在Julia`Array`对象中由`指针’指定的地址,而不创建副本。 指针元素的类型`T’定义数组元素的类型。 'dims’是一个整数(对于一维数组)或数组维度的元组。 'own’另外指示当没有更多对数组的引用时,Julia环境是否应该通过为指针调用`free`来拥有内存。
# '基。pointer_from_objref'-Function
pointer_from_objref(x)
以`Ptr’的形式获取Julia对象的内存地址。 产生的’Ptr’的存在不会保护对象免受垃圾回收,因此必须确保在使用`Ptr`的整个时间内引用对象。
不能为不可变对象调用此函数,因为它们缺少稳定的内存地址。
另请参阅说明 'unsafe_pointer_to_objref'。
# '基。unsafe_pointer_to_objref'-Function
unsafe_pointer_to_objref(p::Ptr)
将`Ptr’转换为对象引用。 假设指针指向在堆上分配的有效Julia对象。 如果不是这种情况,未定义的行为开始生效,因此此函数被认为是"不安全的",应谨慎使用。
另请参阅说明 'pointer_from_objref'。
# '基。disable_sigint'-Function
disable_sigint(f::Function)
在执行当前任务中的函数期间禁用Ctrl-C处理程序,以调用可能调用不安全中断的Julia代码的外部代码。 它的目的是使用"do"块的语法调用,如下所示:
disable_sigint() do # interrupt-unsafe code ... end
它不适用于工作线程’线程。threadid()!=1`),因为’InterruptException’只传递给主线程。 不调用Julia代码或运行时的外部函数会在执行过程中自动禁用信号智能。
# '基。reenable_sigint'-Function
reenable_sigint(f::Function)
在函数执行期间重新启用Ctrl-C处理程序。 暂时取消动作的效果 'disable_sigint'。
# '基。exit_on_sigint'-Function
exit_on_sigint(on::Bool)
设置Julia运行时的`exit_on_sigint’标志。 如果’false',Ctrl-C(SIGINT)固定为 InterruptException'
在`try’块中。 这是REPL中的默认行为:任何代码都使用-e`和'-E’参数执行,Julia脚本使用`-i’参数执行。
如果’true`,Ctrl-C不会导致’InterruptException'。 要在这样的事件中执行代码,需要 'atexit'。 这是在没有'-i`参数的情况下执行Julia脚本的默认行为。
兼容性:Julia1.5
'Exit_on_sigint’函数要求Julia版本至少为1.5。 |
# '基。systemerror'-Function
systemerror(sysfunc[, errno::Cint=Libc.errno()])
systemerror(sysfunc, iftrue::Bool)
如果`iftrue`的值为`true',则使用描述为`sysfunc`的字符串为`errno`调用`SystemError'。
# '基。windowserror'-Function
windowserror(sysfunc[, code::UInt32=Libc.GetLastError()])
windowserror(sysfunc, iftrue::Bool)
同样地 'systemerror',但适用于使用的Windows API函数 `GetLastError'返回错误代码而不是任务 'errno'。
#
'核心。Ref'
-Type</no-翻译>
Ref{T}
安全引用类型为’T’的数据的对象。 这种类型保证指向正确类型的Julia中分配的有效内存。 只要有对`Ref’的引用,底层数据就不会被垃圾回收器释放。
在Julia中,Ref’对象使用
[]'解引用(加载或存储)。
创建具有`T`类型的`x`值的`Ref`通常写为`Ref(x)'。 此外,在创建指向容器(如Array或Ptr)的内部指针时,可以将函数写为`Ref(a,i)`,以创建对`a`元素的`i’的引用。
'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> r = Ref(5) # Создание ссылки с начальным значением
Base.RefValue{Int64}(5)
julia> r[] # Получение значения из Ref
5
julia> r[] = 7 # Сохранение нового значения в Ref
7
julia> r # Ref теперь содержит значение 7
Base.RefValue{Int64}(7)
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
# '基。isassigned'—Method
isassigned(ref::RefValue) -> Bool
例子
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
# '基。Cstring'-Type
Cstring
一个C风格的字符串,由 `Cchar'它自己的字符类型。 'Cstring’以空字符结尾。 有关由自己类型的扩展字符组成的C样式字符串的信息,请参阅说明 'Cwstring'。 有关字符串如何与C交互的详细信息,请参阅 手册。
# '基。Cwstring'-Type
Cwstring
一个C风格的字符串,由 'Cwchar_t'是自定义类型的扩展字符。 'Cwstring’以空字符结尾。 有关由自己类型的字符组成的C样式字符串的信息,请参阅说明 'Cstring'。 有关字符串如何与C交互的详细信息,请参阅 手册。
LLVM接口
# ’核心。内在。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环境的文字字符串(类似于LLVM`define`块),参数可用作连续的未命名SSA变量(%0、%1等)。);
-
以包含IR环境模块的字符串和表示正在调用的入口点函数的名称的字符串的双元素元组的形式。;
-
以双元素元组的形式,模块表示为'向量{UInt8}'带位代码。
请注意,与`ccall’不同,参数类型必须指定为元组类型,而不是类型的元组。 所有类型以及LLVM代码都必须指定为文字,而不是变量或表达式(您可能需要使用`@eval`来创建这些文字)。
https://llvm.org/docs/OpaquePointers.html LLVM代码中不允许使用[不透明指针](写成’ptr')。
见https://github.com/JuliaLang/julia/blob/v1.11.3/test/llvmcall.jl ['test/llvmcall.jl']用例。