diff --git a/doc/manual/calling-c-and-fortran-code.rst b/doc/manual/calling-c-and-fortran-code.rst index 10021797524a64..ce09e3ef1a7243 100644 --- a/doc/manual/calling-c-and-fortran-code.rst +++ b/doc/manual/calling-c-and-fortran-code.rst @@ -15,22 +15,17 @@ with ``ccall`` syntax, which looks like an ordinary function call. The code to be called must be available as a shared library. Most C and Fortran libraries ship compiled as shared libraries already, but if you -are compiling the code yourself using GCC (or Clang), you will need to -use the ``-shared`` and ``-fPIC`` options. The machine instructions -generated by Julia's JIT are the same as a native C call would be, so -the resulting overhead is the same as calling a library function from C -code. (Non-library function calls in both C and Julia can be inlined and -thus may have even less overhead than calls to shared library functions. -When both libraries and executables are generated by LLVM, it is -possible to perform whole-program optimizations that can even optimize -across this boundary, but Julia does not yet support that. In the -future, however, it may do so, yielding even greater performance gains.) +are compiling the code yourself, you need pass the appropriate compiler +flags (e.g., using gcc or clang, you need to use the ``-shared`` and +``-fPIC`` options). The machine instructions generated by Julia's JIT are +the same as a native C call would be, so the resulting overhead is the same +as calling a library function from C code. [#f_inline]_ Shared libraries and functions are referenced by a tuple of the form ``(:function, "library")`` or ``("function", "library")`` where ``function`` -is the C-exported function name. ``library`` refers to the shared library -name: shared libraries available in the (platform-specific) load path -will be resolved by name, and if necessary a direct path may be specified. +is the C-exported function name, and ``library`` refers to the shared library +name. Shared libraries available in the (platform-specific) load path +will be resolved by name. The full path to the library may also be specified. A function name may be used alone in place of the tuple (just ``:function`` or ``"function"``). In this case the name is resolved within @@ -49,19 +44,20 @@ function, all inputs must be passed by reference. Finally, you can use ``ccall`` to actually generate a call to the library function. Arguments to ``ccall`` are as follows: -1. (:function, "library") pair (must be a constant, but see below). +1. The ``(:function, "library")`` pair -2. Return type (see below for mapping the declared C type to Julia) +2. The return type (see `Mapping the declared C type to Julia + <#mapping_c_types_to_julia>`_ below) - - This argument will be evaluated at compile-time. +3. A tuple of input types, corresponding to the function signature (must be + a literal tuple of types, not a variable or expression) -3. A tuple of input types. The input types must be written as a literal tuple, - not a tuple-valued variable or expression. +4. The actual argument values to be passed to the function (if any); each + of these is a separate parameter. - - This argument will be evaluated at compile-time. - -4. The following arguments, if any, are the actual argument values - passed to the function. +The ``(:function, "library")`` pair must be a constant (but see `below +<#non_const_func_spec>`_). The remaining parameters are evaulated at +compile time. As a complete but simple example, the following calls the ``clock`` function from the standard C library:: @@ -75,10 +71,11 @@ function from the standard C library:: julia> typeof(ans) Int32 -``clock`` takes no arguments and returns an ``Int32``. One common gotcha -is that a 1-tuple must be written with a trailing comma. For -example, to call the ``getenv`` function to get a pointer to the value -of an environment variable, one makes a call like this:: +``clock`` takes no arguments and returns an ``Int32``. + +One common gotcha is that a 1-tuple must be written with a trailing +comma. For example, to call the ``getenv`` function to get a pointer to the +value of an environment variable, one makes a call like this:: julia> path = ccall((:getenv, "libc"), Ptr{UInt8}, (Ptr{UInt8},), "SHELL") Ptr{UInt8} @0x00007fff5fbffc45 @@ -86,7 +83,7 @@ of an environment variable, one makes a call like this:: julia> bytestring(path) "/bin/bash" -Note that the argument type tuple must be written as ``(Ptr{UInt8},)``, +The argument type tuple here must be written as ``(Ptr{UInt8},)``, rather than ``(Ptr{UInt8})``. This is because ``(Ptr{UInt8})`` is just the expression ``Ptr{UInt8}`` surrounded by parentheses, rather than a 1-tuple containing ``Ptr{UInt8}``:: @@ -108,12 +105,12 @@ in `env.jl `_:: function getenv(var::AbstractString) - val = ccall((:getenv, "libc"), - Ptr{UInt8}, (Ptr{UInt8},), var) - if val == C_NULL - error("getenv: undefined variable: ", var) - end - bytestring(val) + val = ccall((:getenv, "libc"), + Ptr{UInt8}, (Ptr{UInt8},), var) + if val == C_NULL + error("getenv: undefined variable: ", var) + end + bytestring(val) end The C ``getenv`` function indicates an error by returning ``NULL``, but @@ -132,12 +129,12 @@ Here is a slightly more complex example that discovers the local machine's hostname:: function gethostname() - hostname = Array(UInt8, 128) - ccall((:gethostname, "libc"), Int32, - (Ptr{UInt8}, Csize_t), - hostname, sizeof(hostname)) - hostname[end] = 0; # ensure null-termination - return bytestring(pointer(hostname)) + hostname = Array(UInt8, 128) + ccall((:gethostname, "libc"), Int32, + (Ptr{UInt8}, Csize_t), + hostname, sizeof(hostname)) + hostname[end] = 0; # ensure null-termination + return bytestring(pointer(hostname)) end This example first allocates an array of bytes, then calls the C library @@ -159,7 +156,7 @@ function pointer arguments. For example, to match c-prototypes of the form:: The function `cfunction` generates the c-compatible function pointer for a call to a Julia library function. -Arguments to ``cfunction`` are as follows: +The arguments to ``cfunction`` are: 1. A Julia Function @@ -167,8 +164,7 @@ Arguments to ``cfunction`` are as follows: 3. A tuple of input types -A classic example is the standard C library ``qsort`` function, -declared as:: +As a classic example, consider the standard C library ``qsort`` function:: void qsort(void *base, size_t nmemb, size_t size, int(*compare)(const void *a, const void *b)); @@ -176,19 +172,18 @@ declared as:: The ``base`` argument is a pointer to an array of length ``nmemb``, with elements of ``size`` bytes each. ``compare`` is a callback function which takes pointers to two elements ``a`` and ``b`` and returns an integer less/greater than zero if ``a`` should -appear before/after ``b`` (or zero if any order is permitted). Now, suppose that we -have a 1d array ``A`` of values in Julia that we want to sort using the ``qsort`` -function (rather than Julia's built-in ``sort`` function). Before we worry about calling -``qsort`` and passing arguments, we need to write a comparison function that works for -some arbitrary type T:: - - function mycompare{T}(a::T, b::T) - return convert(Cint, a < b ? -1 : a > b ? +1 : 0)::Cint +appear before/after ``b`` (or zero if any order is permitted). + +Now, suppose that we have a 1d array ``A`` of values in Julia that we want +to sort using the ``qsort`` function (rather than Julia's built-in ``sort`` +function). Before we worry about calling ``qsort`` and passing arguments, +we need to write a comparison function:: + + function mycompare(a, b) + return Cint(a < b ? -1 : a > b ? +1 : 0) end -Notice that we have to be careful about the return type: ``qsort`` expects a function -returning a C ``int``, so we must be sure to return ``Cint`` via a call to ``convert`` -and a ``typeassert``. +``qsort`` expects a function returning a C ``int``, so we must be sure to return ``Cint``. In order to pass this function to C, we obtain its address using the function ``cfunction``:: @@ -205,8 +200,10 @@ The final call to ``qsort`` looks like this:: A, length(A), sizeof(eltype(A)), mycompare_c) After this executes, ``A`` is changed to the sorted array ``[-2.7, 1.3, 3.1, 4.4]``. -Note that Julia knows how to convert an array into a ``Ptr{Cdouble}``, how to compute -the size of a type in bytes (identical to C's ``sizeof`` operator), and so on. +Note that Julia takes care of converting the array to a +``Ptr{Cdouble}``, computing the size of the element type in bytes, and +so on. + For fun, try inserting a ``println("mycompare($a,$b)")`` line into ``mycompare``, which will allow you to see the comparisons that ``qsort`` is performing (and to verify that it is really calling the Julia function that you passed to it). @@ -215,90 +212,87 @@ it is really calling the Julia function that you passed to it). Mapping C Types to Julia ------------------------ -It is critical to exactly match the declared C type with its declaration +.. _mapping_c_types_to_julia: + +It is necessary to exactly match the declared C type with its declaration in Julia. Inconsistencies can cause code that works correctly on one system to fail or produce indeterminate results on a different system. Note that no C header files are used anywhere in the process of calling C -functions: you are responsible for making sure that your Julia types and -call signatures accurately reflect those in the C header file. (The `Clang -package` can be used to auto-generate -Julia code from a C header file.) +functionsl; you are responsible for making sure that your Julia types and +call signatures accurately reflect those in the C header file. [#f_clang_package]_ -Auto-conversion: -~~~~~~~~~~~~~~~~ +Automatic Type Conversion +~~~~~~~~~~~~~~~~~~~~~~~~~ -Julia automatically inserts calls to the ``convert`` function to convert -each argument to the specified type. For example, the following call:: +Julia automatically converts each argument to a ``ccall`` to the specified +type. For example, the following call:: ccall((:foo, "libfoo"), Void, (Int32, Float64), x, y) -will behave as if the following were written:: +will behave as if the following were written [#f_auto_conversion]_:: ccall((:foo, "libfoo"), Void, (Int32, Float64), - Base.cconvert(Int32, Base.cconvert_gcroot(Int32, x)), - Base.cconvert(Float64, Base.cconvert_gcroot(Float64, y))) + convert(Int32, x), convert(Float64, y)) -Note that the primary fall-back method for ``cconvert`` is:: +Type Correspondences +~~~~~~~~~~~~~~~~~~~~ - cconvert(T,x) = convert(T, x) - -and the primary fallback method for ``cconvert_gcroot`` is:: - - cconvert_gcroot(T,x) = x - -Type Correspondences: -~~~~~~~~~~~~~~~~~~~~~ - -First, a review of some relevant Julia type terminology: +First, let's review some relevant Julia type terminology: .. rst-class:: text-wrap ============================== ============================== ====================================================== Syntax / Keyword Example Description ============================== ============================== ====================================================== -``type`` ``ASCIIString`` "Leaf Type" :: A group of related data that includes - a type-tag, is managed by the Julia GC, and - is defined by object-identity. - The type parameters of a leaf type must be fully defined - (no `TypeVars` are allowed) - in order for the instance to be constructed. - -``abstract`` ``Any``, "Super Type" :: A super-type (not a leaf-type) - ``AbstractArray{T,N}``, that cannot be instantiated, but can be used to - ``Complex{T}`` describe a group of types. - -``{T}`` ``Vector{Int}`` "Type Parameter" :: A specialization of a type - (typically used for dispatch or storage optimization). - - "TypeVar" :: The ``T`` in the type parameter declaration - is referred to as a TypeVar (short for type variable). - -``bitstype`` ``Int``, "Bits Type" :: A type with no fields, but a size. It - ``Float64`` is stored and defined by-value. - -``immutable`` ``Pair{Int,Int}`` "Immutable" :: A type with all fields defined to be - constant. It is defined by-value. And may be stored - with a type-tag. - - ``Complex128`` (`isbits`) "Is-Bits" :: A ``bitstype``, or an ``immutable`` type - where all fields are other ``isbits`` types. It is - defined by-value, and is stored without a type-tag. - -``type ...; end`` ``nothing`` "Singleton" :: a Leaf Type or Immutable with no fields. - -``(...)`` or ``tuple(...)``` ``(1,2,3)`` "Tuple" :: an immutable data-structure similar to an - anonymous immutable type, or a constant array. - Represented as either an array or a struct. - -``typealias`` Not applicable here Type aliases, and other similar mechanisms of - doing type indirection, are resolved to their base - type (this includes assigning a type to another name, - or getting the type out of a function call). +``type`` | ``ASCIIString`` | "Leaf Type" :: A group of related data that + | includes a type-tag, is managed by the Julia + | GC, and is defined by object-identity. The + | type parameters of a leaf type must be fully + | defined (no `TypeVars` are allowed) in order + | for the instance to be constructed. + +``abstract`` | ``Any``, | "Super Type" :: A super-type (not a leaf- + | ``AbstractArray{T,N}``, | type) that cannot be instantiated, but can + | ``Complex{T}`` | be used to describe a group of types. + +``{T}`` | ``Vector{Int}`` | "Type Parameter" :: A specialization of a + | type (typically used for dispatch or storage + | optimization). + + | "TypeVar" :: The ``T`` in the type parameter + | declaration is referred to as a TypeVar + | (short for type variable). + +``bitstype`` | ``Int``, | "Bits Type" :: A type with no fields, but a + | ``Float64`` | size. It is stored and defined by-value. + +``immutable`` | ``Pair{String,String}`` | "Immutable" :: A type with all fields defined + | to be constant. It is defined by-value. And + | maybe stored with a type-tag. + + | ``Complex128`` | "Is-Bits" :: A ``bitstype``, or an ``immutable`` + | (`isbits`) | type where all fields are other ``isbits`` + | types. It is defined by-value, and is stored + | without a type-tag. + +``type ...; end`` | ``nothing`` | "Singleton" :: a Leaf Type or Immutable + | with no fields. + +``(...)`` or ``tuple(...)``` | ``(1,2,3)`` | "Tuple" :: an immutable data-structure + | similar to an anonymous immutable type, + | or a constant array. Its storage semantics + | are TBD. + +``typealias`` | Not applicable here | Type aliases, and other similar mechanisms + | of doing type indirection, are resolved to + | their base type (this includes assigning a + | type to another name, or getting the type + | out of a function call). ============================== ============================== ====================================================== -Bits Types: -~~~~~~~~~~~ +Bits Types +~~~~~~~~~~ There are several special types to be aware of, as no other type can be defined to behave the same: @@ -309,9 +303,9 @@ There are several special types to be aware of, as no other type can be defined :Signed: Exactly corresponds to the ``signed`` type annotation in C (or any ``INTEGER`` type in Fortran). Any Julia type that is not a subtype of ``Signed`` is assumed to be unsigned. :Ref{T}: Behaves like a ``Ptr{T}`` that owns its memory. :Array{T,N}: - When an array is passed to C as a ``Ptr{T}`` argument, it is - not reinterpret-cast: Julia requires that the element type of the - array matches ``T``, and then address of the first element is passed. + When an array is passed to C as a ``Ptr{T}`` argument, it is not reinterpreted or + cast to the expected type. Julia requires that the array element type matches + ``T``, and then address of the first element is passed. Therefore, if an ``Array`` contains data in the wrong format, it will have to be explicitly converted using a call such as ``int32(a)``. @@ -327,12 +321,12 @@ There are several special types to be aware of, as no other type can be defined each element replaced by its ``cconvert`` version. This allows, for example, passing an ``argv`` pointer array of type ``Vector{ByteString}`` to an argument of type ``Ptr{Ptr{Cchar}}``. +The following tables give the correspondence between basic C/C++ and Fortran value +types and Julia type. Each C type also has a corresponding Julia type alias, which is +useful for writing portable portable code (and remembering that an int in C is not the +same as an Int in Julia). -On all systems we currently support, basic C/C++ value types may be -translated to Julia types as follows. Every C type also has a corresponding -Julia type with the same name, prefixed by C. This can help for writing portable code (and remembering that an int in C is not the same as an Int in Julia). - -**System Independent:** +**System Independent** .. rst-class:: text-wrap @@ -383,28 +377,31 @@ Julia type with the same name, prefixed by C. This can help for writing portable +-----------------------------------+-----------------+----------------------+-----------------------------------+ | ``void*`` | | | ``Ptr{Void}`` | +-----------------------------------+-----------------+----------------------+-----------------------------------+ -| ``T*`` (where T represents an | | | ``Ref{T}`` | -| appropriately defined type) | | | | +| ``T*`` [#f-T]_ | | | ``Ref{T}`` | +-----------------------------------+-----------------+----------------------+-----------------------------------+ -| ``char*`` | ``CHARACTER*N`` | | ``Cstring`` if NUL-terminated, or | -| (or ``char[]``, e.g. a string) | | | ``Ptr{UInt8}`` if not | +| ``char*`` or ``char[]`` [#f-str]_ | ``CHARACTER*N`` | | ``Cstring`` if NUL-terminated, or | +| | | | ``Ptr{UInt8}`` if not | +-----------------------------------+-----------------+----------------------+-----------------------------------+ -| ``char**`` (or ``*char[]``) | | | ``Ptr{Ptr{UInt8}}`` | +| ``char**`` or ``*char[]`` | | | ``Ptr{Ptr{UInt8}}`` | +-----------------------------------+-----------------+----------------------+-----------------------------------+ -| ``jl_value_t*`` | | | ``Any`` | -| (any Julia Type) | | | | +| ``jl_value_t*`` [#f-jl_value]_ | | | ``Any`` | +-----------------------------------+-----------------+----------------------+-----------------------------------+ -| ``jl_value_t**`` | | | ``Ref{Any}`` | -| (a reference to a Julia Type) | | | | +| ``jl_value_t**`` [#f-jl_value-p]_ | | | ``Ref{Any}`` | +-----------------------------------+-----------------+----------------------+-----------------------------------+ | ``va_arg`` | | | Not supported | +-----------------------------------+-----------------+----------------------+-----------------------------------+ -| ``...`` | | | ```T...``` (where ``T`` | -| (variadic function specification) | | | is one of the above types, | +| ``...`` [#f-vararg] | | | ```T...``` (where ``T`` | +| | | | is one of the above types, | | | | | variadic functions of different | | | | | argument types are not supported) | +-----------------------------------+-----------------+----------------------+-----------------------------------+ +.. [#f-T] where T represents an appropriately defined type +.. [#f-str] i.e., a string +.. [#f-jl_value] any Julia Type +.. [#f-jl_value-p] a reference to a Julia type +.. [#f-vararg] variadic function specification + The ``Cstring`` type is essentially a synonym for ``Ptr{UInt8}``, except the conversion to ``Cstring`` throws an error if the Julia string contains any embedded NUL characters (which would cause the string to be silently truncated if the C routine treats NUL as the terminator). If you are passing a ``char*`` to a C routine that @@ -433,42 +430,63 @@ C name Standard Julia Alias Julia Base Type ``UInt16`` (Windows) ====================== ====================== ======= -`Remember`: when calling a Fortran function, all inputs must be passed by reference, so all type correspondences -above should contain an additional ``Ptr{..}`` or ``Ref{..}`` wrapper around their type specification. +**Mapping Strings to C Types** -`Warning`: For string arguments (``char*``) the Julia type should be ``Cstring`` (if NUL-terminated data is expected) -or either ``Ptr{Cchar}`` or ``Ptr{UInt8}`` otherwise (these two pointer types have the same effect), as described above, -not ``ASCIIString``. Similarly, for array arguments (``T[]`` or ``T*``), the Julia -type should again be ``Ptr{T}``, not ``Vector{T}``. +- For string arguments (``char*``) the Julia type should be ``Cstring`` (if + NUL-terminated data is expected) or either ``Ptr{Cchar}`` or ``Ptr{UInt8}`` + otherwise, as described above. It should *not* be ``ASCIIString``. + +- Similarly, for array arguments (``T[]`` or ``T*``), the Julia type should + again be ``Ptr{T}``, not ``Vector{T}``. -`Warning`: Julia's ``Char`` type is 32 bits, which is not the same as the wide -character type (``wchar_t`` or ``wint_t``) on all platforms. +- Julia's ``Char`` type is 32 bits, which is not the same as the wide character type + (``wchar_t`` or ``wint_t``) on all platforms. -`Note`: For ``wchar_t*`` arguments, the Julia type should be ``Cwstring`` (if the C routine -expects a NUL-terminated string) or ``Ptr{Cwchar_t}`` otherwise, -and data can be converted to/from ordinary Julia strings by the -``wstring(s)`` function (equivalent to either ``utf16(s)`` or ``utf32(s)`` -depending upon the width of ``Cwchar_t``); this conversion will be called -automatically for ``Cwstring`` arguments. Note also that ASCII, UTF-8, -UTF-16, and UTF-32 string data in Julia is internally NUL-terminated, so -it can be passed to C functions expecting NUL-terminated data without making -a copy (but using the ``Cwstring`` type will cause an error to be thrown -if the string itself contains NUL characters). +- For ``wchar_t*`` arguments, the Julia type should be ``Ptr{Wchar_t}``, and data can + be converted to/from ordinary Julia strings by the ``wstring(s)`` function + (equivalent to either ``utf16(s)`` or ``utf32(s)`` depending upon the width of + ``Cwchar_t``. -`Note`: C functions that take an argument of the type ``char**`` can be called by using -a ``Ptr{Ptr{UInt8}}`` type within Julia. For example, -C functions of the form:: +- ASCII, UTF-8, UTF-16, and UTF-32 string data in Julia is internally NUL-terminated, + so it can be passed to C functions expecting NUL-terminated data without making a + copy. + +- For ``wchar_t*`` arguments, the Julia type should be ``Cwstring`` (if the + C routine expects a NUL-terminated string) or ``Ptr{Cwchar_t}`` otherwise. + Data can be converted to/from ordinary Julia strings by the ``wstring(s)`` + function (equivalent to either ``utf16(s)`` or ``utf32(s)`` depending upon + the width of ``Cwchar_t``); this conversion will be called + automatically for ``Cwstring`` arguments. Note also that ASCII, UTF-8, + UTF-16, and UTF-32 string data in Julia is internally NUL-terminated, so + it can be passed to C functions expecting NUL-terminated data without making + a copy (but using the ``Cwstring`` type will cause an error to be thrown + if the string itself contains NUL characters). + +- C functions that take an argument of the type ``char**`` can be called by using + a ``Ptr{Ptr{UInt8}}`` type within Julia. + + For example, C functions of the form:: int main(int argc, char **argv); -can be called via the following Julia code:: + can be called using the following Julia code:: argv = [ "a.out", "arg1", "arg2" ] ccall(:main, Int32, (Int32, Ptr{Ptr{UInt8}}), length(argv), argv) -`Note`: A C function declared to return ``Void`` will return the value ``nothing`` in Julia. +**Miscellaneous Notes** + +- A C function declared to return ``Void`` will return the value ``nothing`` in Julia. + +- When calling a Fortran function, all inputs must be passed by reference, so all type + correspondences above should contain an additional ``Ptr{..}`` or ``Ref{..}`` wrapper + around their type specification. + +- As with ``char*`` arguments, for array arguments (``T[]`` or ``T*``), the Julia type + should be ``Ptr{T}``, and not ``Vector{T}``. + -Struct Type correspondences +Struct Type Correspondences ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Composite types, aka ``struct`` in C or ``TYPE`` in Fortran90 @@ -485,38 +503,39 @@ Instead, declare an immutable isbits type and use that instead. Unnamed structs are not possible in the translation to Julia. Packed structs and union declarations are not supported by Julia. - -You can get a near approximation of a ``union`` if you know, a priori, +You can get an approximation of a ``union`` if you know the field that will have the greatest size (potentially including padding). When translating your fields to Julia, declare the Julia field to be only of that type. -Arrays of parameters must be expanded manually, currently -(either inline, or in an immutable helper-type). For example:: +Arrays of parameters must be expanded manually, currently (either inline, or in an +immutable helper-type). For example, this C struct:: - in C: struct B { int A[3]; }; b_a_2 = B.A[2]; - in Julia: +must be written in Julia as:: + immutable B_A A_1::Cint A_2::Cint A_3::Cint end + type B A::B_A end + b_a_2 = B.A.(2) Arrays of unknown size are not supported. -In the future, some of these restrictions may be reduced or eliminated. +In the future, some of these restrictions may be eliminated. -Memory Ownership: -~~~~~~~~~~~~~~~~~ +Memory Ownership +~~~~~~~~~~~~~~~~ **malloc/free** @@ -533,16 +552,11 @@ to be freed by an external library) is equally invalid. The choice of type-wrapper declaration strongly depends on who allocated the memory, and the declared type. In general, use ``T`` if the memory is intended to be allocated in -(and managed by) Julia (with type-tag). -Use ``Ptr{T}`` if the memory is expected to be populated by ``C`` (without type-tag). +(and managed by) Julia (with a type-tag). +Use ``Ptr{T}`` if the memory is expected to be populated by ``C`` (without a type-tag). Use ``Ref{T}`` if you have an ``isbits`` type, but you want to turn it into a pointer to a struct in another struct definition. -See issue #2818 for some work that needs to be done to simplify this so that Julia -types can be used to recursively mirror c-style structs, -without requiring as much manual management of the ``Ptr`` conversions. -After #2818 is implemented, it will be true that an `Vector{T}` will be equivalent to -an `Ptr{Ptr{T}}`. That is currently not true, and the conversion must be explicitly. Mapping C Functions to Julia ---------------------------- @@ -646,7 +660,6 @@ For translating a ``c`` return type to ``Julia``: + ``Ref{T}``, where ``T`` is the Julia type corresponding to ``T`` + a return type of ``Ref{Any}`` is invalid, it should either be ``Any`` (corresponding to ``jl_value_t*``) or ``Ptr{Any}`` (corresponding to ``Ptr{Any}``) - + currently partially unsupported by cfunction due to #2818 + C **MUST NOT** modify the memory returned via ``Ref{T}`` if ``T`` is an ``isbits`` type + If the memory is owned by C: @@ -675,7 +688,7 @@ Upon return, the contents of ``width`` and ``range`` can be retrieved (if they were changed by ``foo``) by ``width[]`` and ``range[]``; that is, they act like zero-dimensional arrays. -Special Reference Syntax for ccall (deprecated): +Special Reference Syntax for ccall (deprecated) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The ``&`` syntax is deprecated, use the ``Ref{T}`` argument type instead @@ -739,6 +752,8 @@ other ways. Non-constant Function Specifications ------------------------------------ +.. _non_const_func_spec: + A ``(name, library)`` function specification must be a constant expression. However, it is possible to use computed values as function names by staging through ``eval`` as follows:: @@ -927,3 +942,31 @@ Chaining (parentheses optional, but recommended for readability):: @windows? :a : (@osx? :b : :c) +.. [#f_inline] (Non-library function calls in both C and Julia can be + inlined and thus may have even less overhead than calls to shared + library functions. When both libraries and executables are + generated by LLVM, it is possible to perform whole-program + optimizations that can even optimize across this boundary, but + Julia does not yet support that. In the future, however, it may do + so, yielding even greater performance gains.) + + +.. [#f_clang_package] The `Clang package `_ + can be used to auto-generate Julia code from a C header file. + +.. [#f_auto_conversion] + For the conversion of ccall parameters, the actual conversion would look + something like this:: + + ccall((:foo, "libfoo"), Void, (Int32, Float64), + Base.cconvert(Int32, Base.cconvert_gcroot(Int32, x)), + Base.cconvert(Float64, Base.cconvert_gcroot(Float64, y))) + + Note that the primary fall-back method for ``cconvert`` is:: + + cconvert(T,x) = convert(T, x) + + and the primary fallback method for ``cconvert_gcroot`` is:: + + cconvert_gcroot(T,x) = x +