C Interface

Base.@ccallMacro
@ccall library.function_name(argvalue1::argtype1, ...)::returntype
@ccall function_name(argvalue1::argtype1, ...)::returntype
@ccall $function_pointer(argvalue1::argtype1, ...)::returntype

Llama a una función en una biblioteca compartida exportada en C, especificada por library.function_name, donde library es una constante o literal de cadena. La biblioteca puede omitirse, en cuyo caso function_name se resuelve en el proceso actual. Alternativamente, @ccall también se puede usar para llamar a un puntero de función $function_pointer, como uno devuelto por dlsym.

Cada argvalue a @ccall se convierte al correspondiente argtype, mediante la inserción automática de llamadas a unsafe_convert(argtype, cconvert(argtype, argvalue)). (Véase también la documentación de unsafe_convert y cconvert para más detalles.) En la mayoría de los casos, esto simplemente resulta en una llamada a convert(argtype, argvalue).

Ejemplos

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

Esto llama a la función de la biblioteca estándar de C:

size_t strlen(char *)

con una variable de Julia llamada s. Véase también ccall.

Se admiten varargs con la siguiente convención:

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

El punto y coma se utiliza para separar los argumentos requeridos (de los cuales debe haber al menos uno) de los argumentos variádicos.

Ejemplo usando una biblioteca externa:

# Firma C de 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

El literal de cadena también podría usarse directamente antes del nombre de la función, si se desea "libglib-2.0".g_uri_escape_string(...

source
ccallKeyword
ccall((nombre_función, biblioteca), tipo_retorno, (tipo_arg1, ...), valor_arg1, ...)
ccall(nombre_función, tipo_retorno, (tipo_arg1, ...), valor_arg1, ...)
ccall(puntero_función, tipo_retorno, (tipo_arg1, ...), valor_arg1, ...)

Llama a una función en una biblioteca compartida exportada en C, especificada por la tupla (nombre_función, biblioteca), donde cada componente es una cadena o símbolo. En lugar de especificar una biblioteca, también se puede usar un símbolo o cadena nombre_función, que se resuelve en el proceso actual. Alternativamente, ccall también se puede usar para llamar a un puntero de función puntero_función, como el que devuelve dlsym.

Tenga en cuenta que la tupla de tipos de argumento debe ser una tupla literal, y no una variable o expresión de tipo tupla.

Cada valor_arg para el ccall se convertirá al correspondiente tipo_arg, mediante la inserción automática de llamadas a unsafe_convert(tipo_arg, cconvert(tipo_arg, valor_arg)). (Consulte también la documentación de unsafe_convert y cconvert para más detalles). En la mayoría de los casos, esto simplemente resulta en una llamada a convert(tipo_arg, valor_arg).

source
Core.Intrinsics.cglobalFunction
cglobal((symbol, library) [, type=Cvoid])

Obtiene un puntero a una variable global en una biblioteca compartida exportada en C, especificada exactamente como en ccall. Devuelve un Ptr{Type}, que por defecto es Ptr{Cvoid} si no se proporciona un argumento Type. Los valores se pueden leer o escribir mediante unsafe_load o unsafe_store!, respectivamente.

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

Genera un puntero de función llamable en C a partir de la función de Julia callable para la firma de tipo dada. Para pasar el valor de retorno a un ccall, utiliza el tipo de argumento Ptr{Cvoid} en la firma.

Ten en cuenta que la tupla de tipos de argumento debe ser una tupla literal, y no una variable o expresión de tupla (aunque puede incluir una expresión de splat). Y que estos argumentos se evaluarán en el ámbito global durante el tiempo de compilación (no se diferirán hasta el tiempo de ejecución). Agregar un '$' delante del argumento de la función cambia esto para crear en su lugar un cierre en tiempo de ejecución sobre la variable local callable (esto no es compatible con todas las arquitecturas).

Consulta la sección del manual sobre el uso de ccall y cfunction.

Ejemplos

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

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

Manejador de recolección de basura para el valor de retorno de @cfunction cuando el primer argumento está anotado con '$'. Como todos los manejadores de cfunction, debe ser pasado a ccall como un Ptr{Cvoid}, y se convertirá automáticamente en el sitio de llamada al tipo apropiado.

Consulta @cfunction.

source
Base.unsafe_convertFunction
unsafe_convert(T, x)

Convierte x a un argumento C de tipo T donde la entrada x debe ser el valor de retorno de cconvert(T, ...).

En los casos donde convert necesitaría tomar un objeto de Julia y convertirlo en un Ptr, esta función debe ser utilizada para definir y realizar esa conversión.

Ten cuidado de asegurarte de que una referencia de Julia a x exista mientras se utilice el resultado de esta función. En consecuencia, el argumento x para esta función nunca debe ser una expresión, solo un nombre de variable o referencia de campo. Por ejemplo, x=a.b.c es aceptable, pero x=[a,b,c] no lo es.

El prefijo unsafe en esta función indica que usar el resultado de esta función después de que el argumento x de esta función ya no sea accesible para el programa puede causar un comportamiento indefinido, incluyendo corrupción del programa o segfaults, en cualquier momento posterior.

Ver también cconvert

source
Base.cconvertFunction
cconvert(T,x)

Convierte x a un valor que se pasará al código C como tipo T, típicamente llamando a convert(T, x).

En los casos donde x no puede ser convertido de manera segura a T, a diferencia de convert, cconvert puede devolver un objeto de un tipo diferente a T, que sin embargo es adecuado para que unsafe_convert lo maneje. El resultado de esta función debe mantenerse válido (para el GC) hasta que el resultado de unsafe_convert ya no sea necesario. Esto se puede usar para asignar memoria que será accedida por el ccall. Si se necesitan asignar múltiples objetos, se puede usar una tupla de los objetos como valor de retorno.

Ni convert ni cconvert deben tomar un objeto de Julia y convertirlo en un Ptr.

source
Base.unsafe_loadFunction
unsafe_load(p::Ptr{T}, i::Integer=1)
unsafe_load(p::Ptr{T}, order::Symbol)
unsafe_load(p::Ptr{T}, i::Integer, order::Symbol)

Carga un valor del tipo T desde la dirección del elemento i (indexado desde 1) comenzando en p. Esto es equivalente a la expresión en C p[i-1]. Opcionalmente, se puede proporcionar un orden de memoria atómico.

El prefijo unsafe en esta función indica que no se realiza ninguna validación en el puntero p para asegurar que sea válido. Al igual que en C, el programador es responsable de asegurarse de que la memoria referenciada no se libere o se recoja como basura mientras se invoca esta función. Un uso incorrecto puede causar un fallo de segmentación en tu programa o devolver respuestas incorrectas. A diferencia de C, desreferenciar una región de memoria asignada como un tipo diferente puede ser válido siempre que los tipos sean compatibles.

Julia 1.10

El argumento order está disponible a partir de Julia 1.10.

Ver también: atomic

source
Base.unsafe_store!Function
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)

Almacena un valor del tipo T en la dirección del i-ésimo elemento (indexado desde 1) comenzando en p. Esto es equivalente a la expresión en C p[i-1] = x. Opcionalmente, se puede proporcionar un orden de memoria atómico.

El prefijo unsafe en esta función indica que no se realiza ninguna validación en el puntero p para asegurar que sea válido. Al igual que en C, el programador es responsable de asegurarse de que la memoria referenciada no se libere o recolecte mientras se invoca esta función. Un uso incorrecto puede causar un fallo de segmentación en tu programa. A diferencia de C, almacenar en una región de memoria asignada como un tipo diferente puede ser válido siempre que los tipos sean compatibles.

Julia 1.10

El argumento order está disponible a partir de Julia 1.10.

Ver también: atomic

source
Base.unsafe_modify!Function
unsafe_modify!(p::Ptr{T}, op, x, [order::Symbol]) -> Pair

Estas operaciones se realizan atómicamente para obtener y establecer una dirección de memoria después de aplicar la función op. Si es compatible con el hardware (por ejemplo, incremento atómico), esto puede optimizarse a la instrucción de hardware apropiada; de lo contrario, su ejecución será similar a:

y = unsafe_load(p)
z = op(y, x)
unsafe_store!(p, z)
return y => z

El prefijo unsafe en esta función indica que no se realiza ninguna validación en el puntero p para asegurar que sea válido. Al igual que en C, el programador es responsable de asegurarse de que la memoria referenciada no se libere ni se recoja como basura mientras se invoca esta función. Un uso incorrecto puede causar un fallo de segmentación en su programa.

Julia 1.10

Esta función requiere al menos Julia 1.10.

Véase también: modifyproperty!, atomic

source
Base.unsafe_replace!Function
unsafe_replace!(p::Ptr{T}, expected, desired,
               [success_order::Symbol[, fail_order::Symbol=success_order]]) -> (; old, success::Bool)

Estas operaciones se realizan atómicamente para obtener y establecer condicionalmente una dirección de memoria a un valor dado. Si es compatible con el hardware, esto puede optimizarse a la instrucción de hardware apropiada; de lo contrario, su ejecución será similar a:

y = unsafe_load(p, fail_order)
ok = y === expected
if ok
    unsafe_store!(p, desired, success_order)
end
return (; old = y, success = ok)

El prefijo unsafe en esta función indica que no se realiza ninguna validación en el puntero p para asegurar que sea válido. Al igual que en C, el programador es responsable de asegurarse de que la memoria referenciada no se libere ni se recoja como basura mientras se invoca esta función. Un uso incorrecto puede causar un segfault en tu programa.

Julia 1.10

Esta función requiere al menos Julia 1.10.

Ver también: replaceproperty!, atomic

source
Base.unsafe_swap!Function
unsafe_swap!(p::Ptr{T}, x, [order::Symbol])

Estas operaciones se realizan atómicamente para obtener y establecer simultáneamente una dirección de memoria. Si es compatible con el hardware, esto puede optimizarse a la instrucción de hardware apropiada; de lo contrario, su ejecución será similar a:

y = unsafe_load(p)
unsafe_store!(p, x)
return y

El prefijo unsafe en esta función indica que no se realiza ninguna validación en el puntero p para asegurar que sea válido. Al igual que en C, el programador es responsable de asegurarse de que la memoria referenciada no se libere ni se recoja mientras se invoca esta función. Un uso incorrecto puede causar un fallo de segmentación en su programa.

Julia 1.10

Esta función requiere al menos Julia 1.10.

Véase también: swapproperty!, atomic

source
Base.unsafe_copyto!Method
unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)

Copia N elementos de un puntero de origen a un destino, sin ninguna verificación. El tamaño de un elemento se determina por el tipo de los punteros.

El prefijo unsafe en esta función indica que no se realiza ninguna validación en los punteros dest y src para asegurar que sean válidos. Un uso incorrecto puede corromper o causar un fallo de segmentación en tu programa, de la misma manera que en C.

source
Base.unsafe_copyto!Method
unsafe_copyto!(dest::Array, do, src::Array, so, N)

Copia N elementos de un array fuente a un destino, comenzando en el índice lineal so en la fuente y do en el destino (indexado en 1).

El prefijo unsafe en esta función indica que no se realiza ninguna validación para asegurar que N esté dentro de los límites en cualquiera de los arrays. Un uso incorrecto puede corromper o causar un fallo de segmentación en tu programa, de la misma manera que en C.

source
Base.copyto!Function
copyto!(B::AbstractMatrix, ir_dest::AbstractUnitRange, jr_dest::AbstractUnitRange,
        tM::AbstractChar,
        M::AbstractVecOrMat, ir_src::AbstractUnitRange, jr_src::AbstractUnitRange) -> B

Copia eficientemente los elementos de la matriz M a B condicionado al parámetro de carácter tM de la siguiente manera:

tMDestinoFuente
'N'B[ir_dest, jr_dest]M[ir_src, jr_src]
'T'B[ir_dest, jr_dest]transpose(M)[ir_src, jr_src]
'C'B[ir_dest, jr_dest]adjoint(M)[ir_src, jr_src]

Los elementos B[ir_dest, jr_dest] son sobrescritos. Además, los parámetros de rango de índice deben satisfacer length(ir_dest) == length(ir_src) y length(jr_dest) == length(jr_src).

Consulta también copy_transpose! y copy_adjoint!.

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

Copia un UniformScaling a una matriz.

Julia 1.1

En Julia 1.0, este método solo admitía una matriz de destino cuadrada. Julia 1.1 agregó soporte para una matriz rectangular.

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

Copia N elementos de la colección src comenzando en el índice lineal so, al arreglo dest comenzando en el índice do. Devuelve dest.

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

Copia todos los elementos de la colección src al array dest, cuya longitud debe ser mayor o igual a la longitud n de src. Los primeros n elementos de dest son sobrescritos, los otros elementos permanecen intactos.

Véase también copy!, copy.

Warning

El comportamiento puede ser inesperado cuando cualquier argumento mutado comparte memoria con cualquier otro argumento.

Ejemplos

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
source
copyto!(dest, Rdest::CartesianIndices, src, Rsrc::CartesianIndices) -> dest

Copia el bloque de src en el rango de Rsrc al bloque de dest en el rango de Rdest. Los tamaños de las dos regiones deben coincidir.

Ejemplos

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
source
Base.pointerFunction
puntero(array [, index])

Obtiene la dirección nativa de un array o cadena, opcionalmente en una ubicación dada index.

Esta función es "insegura". Ten cuidado de asegurarte de que una referencia de Julia a array exista mientras se use este puntero. El macro GC.@preserve debe ser utilizado para proteger el argumento array de la recolección de basura dentro de un bloque de código dado.

Llamar a Ref(array[, index]) es generalmente preferible a esta función ya que garantiza validez.

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

Envuelve un objeto Array de Julia alrededor de los datos en la dirección dada por pointer, sin hacer una copia. El tipo de elemento del puntero T determina el tipo de elemento del array. dims es un entero (para un array unidimensional) o una tupla de las dimensiones del array. own especifica opcionalmente si Julia debe tomar posesión de la memoria, llamando a free en el puntero cuando el array ya no esté referenciado.

Esta función está etiquetada como "insegura" porque se bloqueará si pointer no es una dirección de memoria válida para datos de la longitud solicitada. A diferencia de unsafe_load y unsafe_store!, el programador también es responsable de asegurarse de que los datos subyacentes no se accedan a través de dos arrays de diferentes tipos de elementos, similar a la regla de aliasing estricto en C.

source
Base.pointer_from_objrefFunction
pointer_from_objref(x)

Obtiene la dirección de memoria de un objeto de Julia como un Ptr. La existencia del Ptr resultante no protegerá al objeto de la recolección de basura, por lo que debes asegurarte de que el objeto permanezca referenciado durante todo el tiempo que se utilizará el Ptr.

Esta función no se puede llamar en objetos inmutables, ya que no tienen direcciones de memoria estables.

Véase también unsafe_pointer_to_objref.

source
Base.unsafe_pointer_to_objrefFunction
unsafe_pointer_to_objref(p::Ptr)

Convierte un Ptr a una referencia de objeto. Asume que el puntero se refiere a un objeto de Julia válido asignado en el heap. Si este no es el caso, resulta en un comportamiento indefinido, por lo que esta función se considera "insegura" y debe usarse con precaución.

Ver también pointer_from_objref.

source
Base.disable_sigintFunction
disable_sigint(f::Function)

Desactiva el controlador de Ctrl-C durante la ejecución de una función en la tarea actual, para llamar a código externo que puede llamar a código julia que no es seguro para interrupciones. Se pretende que se llame utilizando la sintaxis de bloque do de la siguiente manera:

disable_sigint() do
    # código no seguro para interrupciones
    ...
end

Esto no es necesario en hilos de trabajo (Threads.threadid() != 1) ya que la InterruptException solo se entregará al hilo maestro. Las funciones externas que no llaman a código julia o al tiempo de ejecución de julia desactivan automáticamente sigint durante su ejecución.

source
Base.reenable_sigintFunction
reenable_sigint(f::Function)

Vuelve a habilitar el controlador de Ctrl-C durante la ejecución de una función. Revierte temporalmente el efecto de disable_sigint.

source
Base.exit_on_sigintFunction
exit_on_sigint(on::Bool)

Establece la bandera exit_on_sigint del tiempo de ejecución de julia. Si es false, Ctrl-C (SIGINT) se puede capturar como InterruptException en un bloque try. Este es el comportamiento predeterminado en REPL, cualquier código ejecutado a través de -e y -E y en un script de Julia ejecutado con la opción -i.

Si es true, InterruptException no se lanza con Ctrl-C. Ejecutar código ante tal evento requiere atexit. Este es el comportamiento predeterminado en un script de Julia ejecutado sin la opción -i.

Julia 1.5

La función exit_on_sigint requiere al menos Julia 1.5.

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

Lanza un SystemError para errno con la cadena descriptiva sysfunc si iftrue es true

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

Como systemerror, pero para funciones de la API de Windows que utilizan GetLastError para devolver un código de error en lugar de establecer errno.

source
Core.PtrType
Ptr{T}

Una dirección de memoria que se refiere a datos del tipo T. Sin embargo, no hay garantía de que la memoria sea realmente válida, o de que realmente represente datos del tipo especificado.

source
Core.RefType
Ref{T}

Un objeto que referencia de manera segura datos del tipo T. Este tipo está garantizado para apuntar a memoria válida, asignada por Julia, del tipo correcto. Los datos subyacentes están protegidos de ser liberados por el recolector de basura mientras el Ref mismo esté referenciado.

En Julia, los objetos Ref se desreferencian (cargan o almacenan) con [].

La creación de un Ref a un valor x del tipo T se escribe generalmente como Ref(x). Además, para crear punteros interiores a contenedores (como Array o Ptr), se puede escribir Ref(a, i) para crear una referencia al elemento i-ésimo de a.

Ref{T}() crea una referencia a un valor del tipo T sin inicialización. Para un tipo de bits T, el valor será lo que actualmente resida en la memoria asignada. Para un tipo no de bits T, la referencia será indefinida y intentar desreferenciarla resultará en un error, "UndefRefError: acceso a referencia indefinida".

Para verificar si un Ref es una referencia indefinida, utiliza isassigned(ref::RefValue). Por ejemplo, isassigned(Ref{T}()) es false si T no es un tipo de bits. Si T es un tipo de bits, isassigned(Ref{T}()) siempre será verdadero.

Cuando se pasa como un argumento de ccall (ya sea como un tipo Ptr o Ref), un objeto Ref se convertirá en un puntero nativo a los datos que referencia. Para la mayoría de los T, o cuando se convierte a un Ptr{Cvoid}, este es un puntero a los datos del objeto. Cuando T es un tipo isbits, este valor puede ser mutado de manera segura, de lo contrario, la mutación es un comportamiento estrictamente indefinido.

Como un caso especial, establecer T = Any causará en su lugar la creación de un puntero a la referencia misma cuando se convierta a un Ptr{Any} (un jl_value_t const* const* si T es inmutable, de lo contrario un jl_value_t *const *). Cuando se convierte a un Ptr{Cvoid}, seguirá devolviendo un puntero a la región de datos como para cualquier otro T.

Una instancia C_NULL de Ptr puede ser pasada a un argumento Ref de ccall para inicializarlo.

Uso en broadcasting

Ref a veces se utiliza en broadcasting para tratar los valores referenciados como un escalar.

Ejemplos

julia> r = Ref(5) # Crear un Ref con un valor inicial
Base.RefValue{Int64}(5)

julia> r[] # Obtener un valor de un Ref
5

julia> r[] = 7 # Almacenar un nuevo valor en un Ref
7

julia> r # El Ref ahora contiene 7
Base.RefValue{Int64}(7)

julia> isa.(Ref([1,2,3]), [Array, Dict, Int]) # Tratar los valores de referencia como escalares durante el broadcasting
3-element BitVector:
 1
 0
 0

julia> Ref{Function}()  # Referencia indefinida a un tipo no de bits, Function
Base.RefValue{Function}(#undef)

julia> try
           Ref{Function}()[] # Desreferenciar una referencia indefinida resultará en un error
       catch e
           println(e)
       end
UndefRefError()

julia> Ref{Int64}()[]; # Una referencia a un tipo de bits se refiere a un valor indeterminado si no se le da

julia> isassigned(Ref{Int64}()) # Una referencia a un tipo de bits siempre está asignada
true
source
Base.isassignedMethod
isassigned(ref::RefValue) -> Bool

Prueba si el Ref dado está asociado con un valor. Esto siempre es cierto para un Ref de un objeto de tipo bitstype. Devuelve false si la referencia no está definida.

Ejemplos

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

julia> isassigned(ref)
false

julia> ref[] = (foobar(x) = x)
foobar (función genérica con 1 método)

julia> isassigned(ref)
true

julia> isassigned(Ref{Int}())
true
source
Base.CstringType
Cstring

Una cadena de estilo C compuesta por el tipo de carácter nativo Cchars. Los Cstring están terminados en NUL. Para cadenas de estilo C compuestas por el tipo de carácter ancho nativo, consulte Cwstring. Para más información sobre la interoperabilidad de cadenas con C, consulte el manual.

source
Base.CwstringType
Cwstring

Una cadena de estilo C compuesta por el tipo de carácter ancho nativo Cwchar_ts. Los Cwstring están terminados en NUL. Para cadenas de estilo C compuestas por el tipo de carácter nativo, consulte Cstring. Para más información sobre la interoperabilidad de cadenas con C, consulte el manual.

source

LLVM Interface

Core.Intrinsics.llvmcallFunction
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, ...)

Llama el código LLVM proporcionado en el primer argumento. Hay varias formas de especificar este primer argumento:

  • como una cadena literal, que representa IR a nivel de función (similar a un bloque define de LLVM), con argumentos disponibles como variables SSA no nombradas consecutivas (%0, %1, etc.);
  • como una tupla de 2 elementos, que contiene una cadena de IR de módulo y una cadena que representa el nombre de la función de entrada a llamar;
  • como una tupla de 2 elementos, pero con el módulo proporcionado como un Vector{UInt8} con código de bits.

Ten en cuenta que, a diferencia de ccall, los tipos de argumento deben especificarse como un tipo de tupla, y no como una tupla de tipos. Todos los tipos, así como el código LLVM, deben especificarse como literales, y no como variables o expresiones (puede ser necesario usar @eval para generar estos literales).

Los punteros opacos (escritos como ptr) no están permitidos en el código LLVM.

Consulta test/llvmcall.jl para ejemplos de uso.

source