C接口
# *`基地。@ccall`*-马科罗_
@ccall library.function_name(argvalue1::argtype1, ...)::returntype
@ccall function_name(argvalue1::argtype1, ...)::returntype
@ccall $function_pointer(argvalue1::argtype1, ...)::returntype
调用c导出的共享库中的函数,由 图书馆。函数名,在哪里 图书馆 是字符串常量或文字。 库可以被省略,在这种情况下 函数名 在当前进程中被解析。 或者, @ccall 也可用于调用函数指针 $函数_pointer,如一个返回 [医]dlsym.
每个 [医]银价 到 @ccall 被转换为相应的 argtype,argtype,通过自动插入调用到 unsafe_convert(argtype,cconvert(argtype,argvalue)). (另请参阅以下文档 unsafe_转换和 [医转换]更多详情。)在大多数情况下,这只是导致调用 转换(argtype,argvalue).
*例子*
@ccall strlen(s::Cstring)::Csize_t
这将调用C标准库函数:
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声明为 gc_安全 通过使用 gc_safe=真 选项:@ccall gc_safe=true strlen(s::Cstring)::Csize_t这允许垃圾收集器与ccall同时运行,这在 ccall 可能会在茱莉亚外面堵住。 警告:应该谨慎使用此选项,因为如果ccall回调到julia运行时,它可能导致未定义的行为。 (@cfunction/@ccallables 是安全的,但是)
# *`ccall`*-密码_
ccall((function_name, library), returntype, (argtype1, ...), argvalue1, ...)
ccall(function_name, returntype, (argtype1, ...), argvalue1, ...)
ccall(function_pointer, returntype, (argtype1, ...), argvalue1, ...)
调用由元组指定的c导出共享库中的函数 (函数名,库),其中每个组件是字符串或符号。 而不是指定一个库,也可以使用一个 函数名 符号或字符串,在当前进程中解析。 或者, ccall 也可用于调用函数指针 函数_pointer,如一个返回 [医]dlsym.
请注意,参数类型元组必须是字面元组,而不是元组值变量或表达式。
# *`核心。内在。[医]全球`*-函数
cglobal((symbol, library) [, type=Cvoid])
获取指向c导出的共享库中全局变量的指针,该变量的指定与 ccall. 返回a Ptr{Type},违约 Ptr{Cvoid} 如果没有 类型 参数提供。 这些值可以通过以下方式读取或写入 卸载/卸载或 unsafe_store!,分别。
# *`基地。@cfunction`*-马科罗_
@cfunction(callable, ReturnType, (ArgumentTypes...,)) -> Ptr{Cvoid}
@cfunction($callable, ReturnType, (ArgumentTypes...,)) -> CFunction
从Julia函数生成一个c可调用的函数指针 可调用 为给定的类型签名。 将返回值传递给 ccall,使用参数类型 Ptr{Cvoid} 在签名中。
请注意,参数类型元组必须是字面元组,而不是元组值变量或表达式(尽管它可以包括splat表达式)。 并且这些参数将在编译时在全局范围内进行评估(不会延迟到运行时)。 在函数参数前面添加一个'$'会改变它,而是在局部变量上创建一个运行时闭包 可调用 (并非所有体系结构都支持这一点)。
*例子*
julia> function foo(x::Int, y::Int)
return x + y
end
julia> @cfunction(foo, Int, (Int, Int))
Ptr{Cvoid} @0x000000001b82fcd0
# *`基地。[法]结束语`*-类型
CFunction struct
垃圾回收句柄的返回值从 @cfunction 当第一个参数用'$'注释时。 像所有人一样 [法]结束语 句柄,它应该传递给 ccall 作为一个 Ptr{Cvoid},并将在呼叫站点自动转换为适当的类型。
见 @cfunction.
# *`基地。unsafe_转换`*-函数
unsafe_convert(T, x)
转换/转换 x 到类型的C参数 T 输入的位置 x 必须是 cconvert(T,。..).
在以下情况下 转换/转换将需要采取一个朱莉娅对象,并把它变成一个 Ptr,此函数应用于定义和执行该转换。
小心确保Julia引用 x 只要将使用此函数的结果就存在。 因此,论证 x 这个函数不应该是一个表达式,只能是一个变量名或字段引用。 例如, x=a.b.c 是可以接受的,但是 x=[a,b,c] 不是。
该 不安全 此函数的前缀表示在 x 程序不再可访问此函数的参数可能导致未定义的行为,包括程序损坏或分段错误。
请参阅 [医转换]
# *`基地。卸载/卸载`*-函数
unsafe_load(p::Ptr{T}, i::Integer=1)
unsafe_load(p::Ptr{T}, order::Symbol)
unsafe_load(p::Ptr{T}, i::Integer, order::Symbol)
加载类型的值 T 从地址 i第1个元素(1索引)开始于 p. 这相当于C表达式 p[i-1]. 可选地,可以提供原子存储器排序。
该 不安全 此函数上的前缀表示不对指针执行任何验证 p 以确保其有效。 与C一样,程序员负责确保引用的内存在调用此函数时不会被释放或垃圾回收。 不正确的用法可能会使您的程序分段或返回垃圾答案。 与C不同,取消引用分配为不同类型的内存区域可能是有效的,前提是这些类型是兼容的。
|
兼容性
朱莉娅1.10 |
请参阅: 原子
# *`基地。unsafe_store!`*-函数
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)
存储类型的值 T 至 i第1个元素(1索引)开始于 p. 这相当于C表达式 p[i-1]=x. 可选地,可以提供原子存储器排序。
该 不安全 此函数上的前缀表示不对指针执行任何验证 p 以确保其有效。 与C一样,程序员负责确保引用的内存在调用此函数时不会被释放或垃圾回收。 不正确的用法可能会使您的程序中断。 与C不同,存储分配为不同类型的内存区域可能是有效的,前提是这些类型是兼容的。
|
兼容性
朱莉娅1.10 |
请参阅: 原子
# *`基地。unsafe_modify!`*-函数
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
该 不安全 此函数上的前缀表示不对指针执行任何验证 p 以确保其有效。 与C一样,程序员负责确保引用的内存在调用此函数时不会被释放或垃圾回收。 不正确的用法可能会使您的程序中断。
|
兼容性
Julia1.10此功能至少需要Julia1.10。 |
请参阅: modifyproperty!, 原子
# *`基地。unsafe_replace!`*-函数
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)
该 不安全 此函数上的前缀表示不对指针执行任何验证 p 以确保其有效。 与C一样,程序员负责确保引用的内存在调用此函数时不会被释放或垃圾回收。 不正确的用法可能会使您的程序中断。
|
兼容性
Julia1.10此功能至少需要Julia1.10。 |
# *`基地。unsafe_swap!`*-函数
unsafe_swap!(p::Ptr{T}, x, [order::Symbol])
这些原子地执行操作以同时获取和设置内存地址。 如果硬件支持,这可能被优化到适当的硬件指令,否则其执行将类似于:
y = unsafe_load(p)
unsafe_store!(p, x)
return y
该 不安全 此函数上的前缀表示不对指针执行任何验证 p 以确保其有效。 与C一样,程序员负责确保引用的内存在调用此函数时不会被释放或垃圾回收。 不正确的用法可能会使您的程序中断。
|
兼容性
Julia1.10此功能至少需要Julia1.10。 |
请参阅: swapproperty!, 原子
# *`基地。unsafe_copyto!`*-Method
unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)
副本 N 从源指针到目标的元素,没有检查. 元素的大小由指针的类型决定。
该 不安全 此函数的前缀指示对指针不执行验证 德斯特 和 src公司 以确保它们是有效的。 不正确的用法可能会损坏或分段您的程序,与C相同。
# *`基地。unsafe_copyto!`*-Method
unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
副本 n 从源数组到目标的元素,从线性索引开始 抽泣 在源和 多夫斯 在目的地(1索引)。
该 不安全 此函数的prefix指示不执行验证以确保n在任一数组上是inbounds。 不正确的用法可能会损坏或分段您的程序,以与C相同的方式。
# *`基地。收到!`*-函数
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] 被复盖。 此外,索引范围参数必须满足 长度(ir_dest)==长度(ir_src) 和 长度(jr_dest)==长度(jr_src).
请参阅 copy_transpose!和 copy_adjoint!.
copyto!(dest::AbstractMatrix, src::UniformScaling)
副本a 制服,制服到基质上。
|
兼容性
Julia1.1在Julia1.0中,此方法仅支持正方形目标矩阵。 朱莉娅1.1。 增加了对矩形矩阵的支持。 |
copyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest
复制 src公司 范围内的 Rsrc 到 德斯特 范围内的 最大的. 两个区域的大小必须匹配。
*例子*
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::AbstractArray, src) -> dest
从集合中复制所有元素 src公司 到阵列 德斯特,其长度必须大于或等于长度 n 的 src公司. 第一个 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, doffs, src, soffs, n)
副本 n 集合中的元素 src公司 从线性索引开始 啜泣,到数组 德斯特 从索引开始 多夫斯. 回来吧 德斯特.
# *`基地。指针`*-函数
pointer(array [, index])
获取数组或字符串的本机地址,可选地在给定位置 索引.
此功能"不安全"。 小心确保Julia引用 阵列 只要将使用此指针就存在。 该 GC。@保留宏应用于保护 阵列 来自给定代码块内垃圾回收的参数。
打电话来 Ref(数组[,索引])通常比这个函数更好,因为它保证了有效性。
# *`基地。unsafe_wrap`*-Method
unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)
包一个朱莉娅 阵列 对象周围的数据在给定的地址 指针,而不制作副本。 指针元素类型 T 确定数组元素类型。 暗淡无光 是整数(对于一维数组)或数组维度的元组。 自己的 可选地指定Julia是否应该获得内存的所有权,调用 免费 当数组不再被引用时,指针上。
此函数被标记为"不安全",因为如果 指针 不是所请求长度的数据的有效内存地址。 不像 卸载/卸载和 unsafe_store!,程序员还负责确保底层数据不通过两个不同元素类型的数组访问,类似于c中的严格别名规则。
# *`基地。pointer_from_objref`*-函数
pointer_from_objref(x)
获取Julia对象的内存地址为 Ptr. 产生的存在 Ptr 不会保护对象免受垃圾回收,因此您必须确保对象在整个时间内保持引用 Ptr 将被使用。
不能对不可变对象调用此函数,因为它们没有稳定的内存地址。
# *`基地。unsafe_pointer_to_objref`*-函数
unsafe_pointer_to_objref(p::Ptr)
转换a Ptr 到一个对象引用。 假设指针指向有效的堆分配Julia对象。 如果不是这种情况,未定义的行为结果,因此这个函数被认为是"不安全的",应该小心使用。
请参阅 pointer_from_objref.
# *`基地。禁用_sigint`*-函数
disable_sigint(f::Function)
在执行当前任务上的函数期间禁用Ctrl-C处理程序,用于调用可能调用非中断安全的julia代码的外部代码。 拟被调用使用 做 块语法如下:
disable_sigint() do
# interrupt-unsafe code
...
end
这在工作线程上不需要(线程。threadid()!= 1)自 InterruptException异常 只会传递给主线程。 不调用julia代码或julia运行时的外部函数在执行过程中会自动禁用sigint。
# *`基地。exit_on_sigint`*-函数
exit_on_sigint(on::Bool)
套装 exit_on_sigint julia运行时的标志。 如果 错误,Ctrl-C(SIGINT)是capturable为 InterruptException异常在 试试 块。 这是REPL中的默认行为,任何代码都通过 -e 和 -E 而在朱莉娅脚本运行 -我 选择。
如果 真的, InterruptException异常 不被Ctrl-C抛出。在这样的事件上运行代码需要 atexit,atexit. 这是Julia脚本运行中的默认行为 -我 选择。
|
兼容性
Julia1.5功能 |
# *`基地。系统错误`*-函数
systemerror(sysfunc[, errno::Cint=Libc.errno()])
systemerror(sysfunc, iftrue::Bool)
提出一个 系统错误 为 厄尔诺 使用描述性字符串 sysfunc 如果 iftrue 是 真的
# *`核心。参考书`*-类型
Ref{T}
安全引用类型数据的对象 T. 此类型保证指向正确类型的有效,Julia分配的内存。 垃圾回收器保护底层数据不被释放,只要 参考书 本身被引用。
在朱莉娅, 参考书 对象被取消引用(加载或存储) [].
创建一个 参考书 到一个值 x 类型 T 通常是写的 参考(x). 此外,对于创建指向容器(如Array或Ptr)的内部指针,可以编写 参考(a,i) 用于创建对 i-第三要素 a.
参考{T}() 创建对类型值的引用 T 没有初始化。 对于bitstype T,该值将是当前驻留在分配的内存中的任何内容。 对于非bitstype T,引用将是未定义的,并且试图取消引用它将导致错误,"UndefRefError:对未定义引用的访问"。
检查是否 参考书 是未定义的引用,使用 isassigned(ref::RefValue). 例如, isassigned(Ref{T}()) 是 错误 如果 T 不是bitstype。 如果 T 是bitstype, isassigned(Ref{T}()) 永远都是真的。
当通过作为一个 ccall 参数(无论是作为一个 Ptr 或 参考书 型),a 参考书 对象将被转换为指向其引用的数据的本机指针。 对于大多数 T,或当转换为 Ptr{Cvoid},这是一个指向对象数据的指针。 何时 T 是一个 轨道,轨道 类型,该值可以被安全地突变,否则突变是严格未定义的行为。
作为特例,设置 T=任何 将导致创建一个指向引用本身的指针,当转换为 Ptr{Any} (一 jl_value_t const*const* 如果T是不可变的,否则a jl_value_t*const *). 当转换为 Ptr{Cvoid},它仍然会像任何其他一样返回指向数据区域的指针 T.
A C_NULL 的实例 Ptr 可以传递给一个 ccall 参考书 参数来初始化它。
*广播用途*
参考书 有时在广播中使用,以便将引用的值视为标量。
*例子*
julia> r = Ref(5) # Create a Ref with an initial value
Base.RefValue{Int64}(5)
julia> r[] # Getting a value from a Ref
5
julia> r[] = 7 # Storing a new value in a Ref
7
julia> r # The Ref now contains 7
Base.RefValue{Int64}(7)
julia> isa.(Ref([1,2,3]), [Array, Dict, Int]) # Treat reference values as scalar during broadcasting
3-element BitVector:
1
0
0
julia> Ref{Function}() # Undefined reference to a non-bitstype, Function
Base.RefValue{Function}(#undef)
julia> try
Ref{Function}()[] # Dereferencing an undefined reference will result in an error
catch e
println(e)
end
UndefRefError()
julia> Ref{Int64}()[]; # A reference to a bitstype refers to an undetermined value if not given
julia> isassigned(Ref{Int64}()) # A reference to a bitstype is always assigned
true
# *`基地。is分配`*-Method
isassigned(ref::RefValue) -> Bool
测试是否给定 参考书与一个值相关联。 对于一个 参考书 bitstype对象的。 回来吧 错误 如果引用未定义。
*例子*
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
# *`基地。C字符串`*-类型
Cstring
由本机字符类型组成的C样式字符串 Cchars. C字符串s为零终止。 对于由本机宽字符类型组成的C样式字符串,请参阅 Cwstring/Cwstring. 有关与C的字符串互操作性的更多信息,请参阅 手册。
LLVM接口
# *`核心。内在。n.有限责任公司`*-函数
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 定义 块),参数作为连续的未命名SSA变量(%0、%1等)可用。);
*作为2元素元组,包含模块IR的字符串和表示要调用的入口点函数名称的字符串;
*作为一个2元素元组,但模块作为一个 向量{UInt8} 用比特码。
请注意,与 ccall 参数类型必须指定为元组类型,而不是类型的元组。 所有类型以及LLVM代码都应指定为文字,而不是变量或表达式(可能需要使用 @eval 以生成这些文字)。
见https://github.com/JuliaLang/julia/blob/v1.12.5/test/llvmcall.jl[脧锚脧赂`测试/llvmcall。jl`]用于使用示例。