{
    "content": [
        {
            "type": "text",
            "text": "# L (info)\n\n## Sections\n\n- **libffi**\n- **1 What is libffi?**\n- **2 Using libffi** (7 subsections)\n- **3 Memory Usage**\n- **4 Missing Features**\n- **Index**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "L",
        "section": "",
        "mode": "info",
        "summary": null,
        "synopsis": null,
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "libffi",
                "lines": 34,
                "subsections": []
            },
            {
                "name": "1 What is libffi?",
                "lines": 29,
                "subsections": []
            },
            {
                "name": "2 Using libffi",
                "lines": 12,
                "subsections": [
                    {
                        "name": "2.1 The Basics",
                        "lines": 104
                    },
                    {
                        "name": "2.2 Simple Example",
                        "lines": 37
                    },
                    {
                        "name": "2.3 Types",
                        "lines": 435
                    },
                    {
                        "name": "2.4 Multiple ABIs",
                        "lines": 8
                    },
                    {
                        "name": "2.5 The Closure API",
                        "lines": 93
                    },
                    {
                        "name": "2.6 Closure Example",
                        "lines": 55
                    },
                    {
                        "name": "2.7 Thread Safety",
                        "lines": 18
                    }
                ]
            },
            {
                "name": "3 Memory Usage",
                "lines": 33,
                "subsections": []
            },
            {
                "name": "4 Missing Features",
                "lines": 13,
                "subsections": []
            },
            {
                "name": "Index",
                "lines": 55,
                "subsections": []
            }
        ],
        "sections": {
            "libffi": {
                "content": "This manual is for libffi, a portable foreign function interface\nlibrary.\n\nCopyright (C) 2008-2019, 2021 Anthony Green and Red Hat, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n* Menu:\n\n* Introduction::                What is libffi?\n* Using libffi::                How to use libffi.\n* Memory Usage::                Where memory for closures comes from.\n* Missing Features::            Things libffi can't do.\n* Index::                       Index.\n\nFile: libffi.info,  Node: Introduction,  Next: Using libffi,  Prev: Top,  Up: Top\n",
                "subsections": []
            },
            "1 What is libffi?": {
                "content": "Compilers for high level languages generate code that follow certain\nconventions.  These conventions are necessary, in part, for separate\ncompilation to work.  One such convention is the \"calling convention\".\nThe calling convention is a set of assumptions made by the compiler\nabout where function arguments will be found on entry to a function.  A\ncalling convention also specifies where the return value for a function\nis found.  The calling convention is also sometimes called the \"ABI\" or\n\"Application Binary Interface\".\n\nSome programs may not know at the time of compilation what arguments\nare to be passed to a function.  For instance, an interpreter may be\ntold at run-time about the number and types of arguments used to call a\ngiven function.  'Libffi' can be used in such programs to provide a\nbridge from the interpreter program to compiled code.\n\nThe 'libffi' library provides a portable, high level programming\ninterface to various calling conventions.  This allows a programmer to\ncall any function specified by a call interface description at run time.\n\nFFI stands for Foreign Function Interface.  A foreign function\ninterface is the popular name for the interface that allows code written\nin one language to call code written in another language.  The 'libffi'\nlibrary really only provides the lowest, machine dependent layer of a\nfully featured foreign function interface.  A layer must exist above\n'libffi' that handles type conversions for values passed between the two\nlanguages.\n\nFile: libffi.info,  Node: Using libffi,  Next: Memory Usage,  Prev: Introduction,  Up: Top\n",
                "subsections": []
            },
            "2 Using libffi": {
                "content": "* Menu:\n\n* The Basics::                  The basic libffi API.\n* Simple Example::              A simple example.\n* Types::                       libffi type descriptions.\n* Multiple ABIs::               Different passing styles on one platform.\n* The Closure API::             Writing a generic function.\n* Closure Example::             A closure example.\n* Thread Safety::               Thread safety.\n\nFile: libffi.info,  Node: The Basics,  Next: Simple Example,  Up: Using libffi\n",
                "subsections": [
                    {
                        "name": "2.1 The Basics",
                        "content": "'Libffi' assumes that you have a pointer to the function you wish to\ncall and that you know the number and types of arguments to pass it, as\nwell as the return type of the function.\n\nThe first thing you must do is create an 'fficif' object that\nmatches the signature of the function you wish to call.  This is a\nseparate step because it is common to make multiple calls using a single\n'fficif'.  The \"cif\" in 'fficif' stands for Call InterFace.  To\nprepare a call interface object, use the function 'ffiprepcif'.\n\n-- Function: ffistatus ffiprepcif (fficif *CIF, ffiabi ABI,\nunsigned int NARGS, ffitype *RTYPE, ffitype ARGTYPES)\nThis initializes CIF according to the given parameters.\n\nABI is the ABI to use; normally 'FFIDEFAULTABI' is what you want.\n*note Multiple ABIs:: for more information.\n\nNARGS is the number of arguments that this function accepts.\n\nRTYPE is a pointer to an 'ffitype' structure that describes the\nreturn type of the function.  *Note Types::.\n\nARGTYPES is a vector of 'ffitype' pointers.  ARGTYPES must have\nNARGS elements.  If NARGS is 0, this argument is ignored.\n\n'ffiprepcif' returns a 'libffi' status code, of type\n'ffistatus'.  This will be either 'FFIOK' if everything worked\nproperly; 'FFIBADTYPEDEF' if one of the 'ffitype' objects is\nincorrect; or 'FFIBADABI' if the ABI parameter is invalid.\n\nIf the function being called is variadic (varargs) then\n'ffiprepcifvar' must be used instead of 'ffiprepcif'.\n\n-- Function: ffistatus ffiprepcifvar (fficif *CIF, ffiabi ABI,\nunsigned int NFIXEDARGS, unsigned int NTOTALARGS, ffitype\n*RTYPE, ffitype ARGTYPES)\nThis initializes CIF according to the given parameters for a call\nto a variadic function.  In general its operation is the same as\nfor 'ffiprepcif' except that:\n\nNFIXEDARGS is the number of fixed arguments, prior to any variadic\narguments.  It must be greater than zero.\n\nNTOTALARGS the total number of arguments, including variadic and\nfixed arguments.  ARGTYPES must have this many elements.\n\n'ffiprepcifvar' will return 'FFIBADARGTYPE' if any of the\nvariable argument types are 'ffitypefloat' (promote to\n'ffitypedouble' first), or any integer type small than an int\n(promote to an int-sized type first).\n\nNote that, different cif's must be prepped for calls to the same\nfunction when different numbers of arguments are passed.\n\nAlso note that a call to 'ffiprepcifvar' with\nNFIXEDARGS=NOTOTALARGS is NOT equivalent to a call to\n'ffiprepcif'.\n\nNote that the resulting 'fficif' holds pointers to all the\n'ffitype' objects that were used during initialization.  You must\nensure that these type objects have a lifetime at least as long as that\nof the 'fficif'.\n\nTo call a function using an initialized 'fficif', use the 'fficall'\nfunction:\n\n-- Function: void fficall (fficif *CIF, void *FN, void *RVALUE, void\nAVALUES)\nThis calls the function FN according to the description given in\nCIF.  CIF must have already been prepared using 'ffiprepcif'.\n\nRVALUE is a pointer to a chunk of memory that will hold the result\nof the function call.  This must be large enough to hold the\nresult, no smaller than the system register size (generally 32 or\n64 bits), and must be suitably aligned; it is the caller's\nresponsibility to ensure this.  If CIF declares that the function\nreturns 'void' (using 'ffitypevoid'), then RVALUE is ignored.\n\nIn most situations, 'libffi' will handle promotion according to the\nABI. However, for historical reasons, there is a special case with\nreturn values that must be handled by your code.  In particular,\nfor integral (not 'struct') types that are narrower than the system\nregister size, the return value will be widened by 'libffi'.\n'libffi' provides a type, 'ffiarg', that can be used as the return\ntype.  For example, if the CIF was defined with a return type of\n'char', 'libffi' will try to store a full 'ffiarg' into the return\nvalue.\n\nAVALUES is a vector of 'void *' pointers that point to the memory\nlocations holding the argument values for a call.  If CIF declares\nthat the function has no arguments (i.e., NARGS was 0), then\nAVALUES is ignored.  Note that argument values may be modified by\nthe callee (for instance, structs passed by value); the burden of\ncopying pass-by-value arguments is placed on the caller.\n\nNote that while the return value must be register-sized, arguments\nshould exactly match their declared type.  For example, if an\nargument is a 'short', then the entry in AVALUES should point to an\nobject declared as 'short'; but if the return type is 'short', then\nRVALUE should point to an object declared as a larger type -\nusually 'ffiarg'.\n\nFile: libffi.info,  Node: Simple Example,  Next: Types,  Prev: The Basics,  Up: Using libffi\n"
                    },
                    {
                        "name": "2.2 Simple Example",
                        "content": "Here is a trivial example that calls 'puts' a few times.\n\n#include <stdio.h>\n#include <ffi.h>\n\nint main()\n{\nfficif cif;\nffitype *args[1];\nvoid *values[1];\nchar *s;\nffiarg rc;\n\n/* Initialize the argument info vectors */\nargs[0] = &ffitypepointer;\nvalues[0] = &s;\n\n/* Initialize the cif */\nif (ffiprepcif(&cif, FFIDEFAULTABI, 1,\n&ffitypesint, args) == FFIOK)\n{\ns = \"Hello World!\";\nfficall(&cif, puts, &rc, values);\n/* rc now holds the result of the call to puts */\n\n/* values holds a pointer to the function's arg, so to\ncall puts() again all we need to do is change the\nvalue of s */\ns = \"This is cool!\";\nfficall(&cif, puts, &rc, values);\n}\n\nreturn 0;\n}\n\nFile: libffi.info,  Node: Types,  Next: Multiple ABIs,  Prev: Simple Example,  Up: Using libffi\n"
                    },
                    {
                        "name": "2.3 Types",
                        "content": "* Menu:\n\n* Primitive Types::             Built-in types.\n* Structures::                  Structure types.\n* Size and Alignment::          Size and alignment of types.\n* Arrays Unions Enums::         Arrays, unions, and enumerations.\n* Type Example::                Structure type example.\n* Complex::                     Complex types.\n* Complex Type Example::        Complex type example.\n\nFile: libffi.info,  Node: Primitive Types,  Next: Structures,  Up: Types\n\n\n'Libffi' provides a number of built-in type descriptors that can be used\nto describe argument and return types:\n\n'ffitypevoid'\nThe type 'void'.  This cannot be used for argument types, only for\nreturn values.\n\n'ffitypeuint8'\nAn unsigned, 8-bit integer type.\n\n'ffitypesint8'\nA signed, 8-bit integer type.\n\n'ffitypeuint16'\nAn unsigned, 16-bit integer type.\n\n'ffitypesint16'\nA signed, 16-bit integer type.\n\n'ffitypeuint32'\nAn unsigned, 32-bit integer type.\n\n'ffitypesint32'\nA signed, 32-bit integer type.\n\n'ffitypeuint64'\nAn unsigned, 64-bit integer type.\n\n'ffitypesint64'\nA signed, 64-bit integer type.\n\n'ffitypefloat'\nThe C 'float' type.\n\n'ffitypedouble'\nThe C 'double' type.\n\n'ffitypeuchar'\nThe C 'unsigned char' type.\n\n'ffitypeschar'\nThe C 'signed char' type.  (Note that there is not an exact\nequivalent to the C 'char' type in 'libffi'; ordinarily you should\neither use 'ffitypeschar' or 'ffitypeuchar' depending on\nwhether 'char' is signed.)\n\n'ffitypeushort'\nThe C 'unsigned short' type.\n\n'ffitypesshort'\nThe C 'short' type.\n\n'ffitypeuint'\nThe C 'unsigned int' type.\n\n'ffitypesint'\nThe C 'int' type.\n\n'ffitypeulong'\nThe C 'unsigned long' type.\n\n'ffitypeslong'\nThe C 'long' type.\n\n'ffitypelongdouble'\nOn platforms that have a C 'long double' type, this is defined.  On\nother platforms, it is not.\n\n'ffitypepointer'\nA generic 'void *' pointer.  You should use this for all pointers,\nregardless of their real type.\n\n'ffitypecomplexfloat'\nThe C 'Complex float' type.\n\n'ffitypecomplexdouble'\nThe C 'Complex double' type.\n\n'ffitypecomplexlongdouble'\nThe C 'Complex long double' type.  On platforms that have a C\n'long double' type, this is defined.  On other platforms, it is\nnot.\n\nEach of these is of type 'ffitype', so you must take the address\nwhen passing to 'ffiprepcif'.\n\nFile: libffi.info,  Node: Structures,  Next: Size and Alignment,  Prev: Primitive Types,  Up: Types\n\n\n'libffi' is perfectly happy passing structures back and forth.  You must\nfirst describe the structure to 'libffi' by creating a new 'ffitype'\nobject for it.\n\n-- Data type: ffitype\nThe 'ffitype' has the following members:\n'sizet size'\nThis is set by 'libffi'; you should initialize it to zero.\n\n'unsigned short alignment'\nThis is set by 'libffi'; you should initialize it to zero.\n\n'unsigned short type'\nFor a structure, this should be set to 'FFITYPESTRUCT'.\n\n'ffitype elements'\nThis is a 'NULL'-terminated array of pointers to 'ffitype'\nobjects.  There is one element per field of the struct.\n\nNote that 'libffi' has no special support for bit-fields.  You\nmust manage these manually.\n\nThe 'size' and 'alignment' fields will be filled in by 'ffiprepcif'\nor 'ffiprepcifvar', as needed.\n\nFile: libffi.info,  Node: Size and Alignment,  Next: Arrays Unions Enums,  Prev: Structures,  Up: Types\n\n\n'libffi' will set the 'size' and 'alignment' fields of an 'ffitype'\nobject for you.  It does so using its knowledge of the ABI.\n\nYou might expect that you can simply read these fields for a type\nthat has been laid out by 'libffi'.  However, there are some caveats.\n\n* The size or alignment of some of the built-in types may vary\ndepending on the chosen ABI.\n\n* The size and alignment of a new structure type will not be set by\n'libffi' until it has been passed to 'ffiprepcif' or\n'ffigetstructoffsets'.\n\n* A structure type cannot be shared across ABIs.  Instead each ABI\nneeds its own copy of the structure type.\n\nSo, before examining these fields, it is safest to pass the\n'ffitype' object to 'ffiprepcif' or 'ffigetstructoffsets' first.\nThis function will do all the needed setup.\n\nffitype *desiredtype;\nffiabi desiredabi;\n...\nfficif cif;\nif (ffiprepcif (&cif, desiredabi, 0, desiredtype, NULL) == FFIOK)\n{\nsizet size = desiredtype->size;\nunsigned short alignment = desiredtype->alignment;\n}\n\n'libffi' also provides a way to get the offsets of the members of a\nstructure.\n\n-- Function: ffistatus ffigetstructoffsets (ffiabi abi, ffitype\n*structtype, sizet *offsets)\nCompute the offset of each element of the given structure type.\nABI is the ABI to use; this is needed because in some cases the\nlayout depends on the ABI.\n\nOFFSETS is an out parameter.  The caller is responsible for\nproviding enough space for all the results to be written - one\nelement per element type in STRUCTTYPE.  If OFFSETS is 'NULL',\nthen the type will be laid out but not otherwise modified.  This\ncan be useful for accessing the type's size or layout, as mentioned\nabove.\n\nThis function returns 'FFIOK' on success; 'FFIBADABI' if ABI is\ninvalid; or 'FFIBADTYPEDEF' if STRUCTTYPE is invalid in some\nway.  Note that only 'FFISTRUCT' types are valid here.\n\nFile: libffi.info,  Node: Arrays Unions Enums,  Next: Type Example,  Prev: Size and Alignment,  Up: Types\n\n\n2.3.4.1 Arrays\n..............\n\n'libffi' does not have direct support for arrays or unions.  However,\nthey can be emulated using structures.\n\nTo emulate an array, simply create an 'ffitype' using\n'FFITYPESTRUCT' with as many members as there are elements in the\narray.\n\nffitype arraytype;\nffitype elements\nint i;\n\nelements = malloc ((n + 1) * sizeof (ffitype *));\nfor (i = 0; i < n; ++i)\nelements[i] = arrayelementtype;\nelements[n] = NULL;\n\narraytype.size = arraytype.alignment = 0;\narraytype.type = FFITYPESTRUCT;\narraytype.elements = elements;\n\nNote that arrays cannot be passed or returned by value in C -\nstructure types created like this should only be used to refer to\nmembers of real 'FFITYPESTRUCT' objects.\n\nHowever, a phony array type like this will not cause any errors from\n'libffi' if you use it as an argument or return type.  This may be\nconfusing.\n\n2.3.4.2 Unions\n..............\n\nA union can also be emulated using 'FFITYPESTRUCT'.  In this case,\nhowever, you must make sure that the size and alignment match the real\nrequirements of the union.\n\nOne simple way to do this is to ensue that each element type is laid\nout.  Then, give the new structure type a single element; the size of\nthe largest element; and the largest alignment seen as well.\n\nThis example uses the 'ffiprepcif' trick to ensure that each\nelement type is laid out.\n\nffiabi desiredabi;\nffitype uniontype;\nffitype unionelements;\n\nint i;\nffitype elementtypes[2];\n\nelementtypes[1] = NULL;\n\nuniontype.size = uniontype.alignment = 0;\nuniontype.type = FFITYPESTRUCT;\nuniontype.elements = elementtypes;\n\nfor (i = 0; unionelements[i]; ++i)\n{\nfficif cif;\nif (ffiprepcif (&cif, desiredabi, 0, unionelements[i], NULL) == FFIOK)\n{\nif (unionelements[i]->size > uniontype.size)\n{\nuniontype.size = unionelements[i];\nsize = unionelements[i]->size;\n}\nif (unionelements[i]->alignment > uniontype.alignment)\nuniontype.alignment = unionelements[i]->alignment;\n}\n}\n\n2.3.4.3 Enumerations\n....................\n\n'libffi' does not have any special support for C 'enum's.  Although any\ngiven 'enum' is implemented using a specific underlying integral type,\nexactly which type will be used cannot be determined by 'libffi' - it\nmay depend on the values in the enumeration or on compiler flags such as\n'-fshort-enums'.  *Note (gcc)Structures unions enumerations and\nbit-fields implementation::, for more information about how GCC handles\nenumerations.\n\nFile: libffi.info,  Node: Type Example,  Next: Complex,  Prev: Arrays Unions Enums,  Up: Types\n\n\nThe following example initializes a 'ffitype' object representing the\n'tm' struct from Linux's 'time.h'.\n\nHere is how the struct is defined:\n\nstruct tm {\nint tmsec;\nint tmmin;\nint tmhour;\nint tmmday;\nint tmmon;\nint tmyear;\nint tmwday;\nint tmyday;\nint tmisdst;\n/* Those are for future use. */\nlong int tmgmtoff;\nconst char *tmzone;\n};\n\nHere is the corresponding code to describe this struct to 'libffi':\n\n{\nffitype tmtype;\nffitype *tmtypeelements[12];\nint i;\n\ntmtype.size = tmtype.alignment = 0;\ntmtype.type = FFITYPESTRUCT;\ntmtype.elements = &tmtypeelements;\n\nfor (i = 0; i < 9; i++)\ntmtypeelements[i] = &ffitypesint;\n\ntmtypeelements[9] = &ffitypeslong;\ntmtypeelements[10] = &ffitypepointer;\ntmtypeelements[11] = NULL;\n\n/* tmtype can now be used to represent tm argument types and\nreturn types for ffiprepcif() */\n}\n\nFile: libffi.info,  Node: Complex,  Next: Complex Type Example,  Prev: Type Example,  Up: Types\n\n\n'libffi' supports the complex types defined by the C99 standard\n('Complex float', 'Complex double' and 'Complex long double' with the\nbuilt-in type descriptors 'ffitypecomplexfloat',\n'ffitypecomplexdouble' and 'ffitypecomplexlongdouble'.\n\nCustom complex types like 'Complex int' can also be used.  An\n'ffitype' object has to be defined to describe the complex type to\n'libffi'.\n\n-- Data type: ffitype\n'sizet size'\nThis must be manually set to the size of the complex type.\n\n'unsigned short alignment'\nThis must be manually set to the alignment of the complex\ntype.\n\n'unsigned short type'\nFor a complex type, this must be set to 'FFITYPECOMPLEX'.\n\n'ffitype elements'\n\nThis is a 'NULL'-terminated array of pointers to 'ffitype'\nobjects.  The first element is set to the 'ffitype' of the\ncomplex's base type.  The second element must be set to\n'NULL'.\n\nThe section *note Complex Type Example:: shows a way to determine the\n'size' and 'alignment' members in a platform independent way.\n\nFor platforms that have no complex support in 'libffi' yet, the\nfunctions 'ffiprepcif' and 'ffiprepargs' abort the program if they\nencounter a complex type.\n\nFile: libffi.info,  Node: Complex Type Example,  Prev: Complex,  Up: Types\n\n\nThis example demonstrates how to use complex types:\n\n#include <stdio.h>\n#include <ffi.h>\n#include <complex.h>\n\nvoid complexfn(Complex float cf,\nComplex double cd,\nComplex long double cld)\n{\nprintf(\"cf=%f+%fi\\ncd=%f+%fi\\ncld=%f+%fi\\n\",\n(float)creal (cf), (float)cimag (cf),\n(float)creal (cd), (float)cimag (cd),\n(float)creal (cld), (float)cimag (cld));\n}\n\nint main()\n{\nfficif cif;\nffitype *args[3];\nvoid *values[3];\nComplex float cf;\nComplex double cd;\nComplex long double cld;\n\n/* Initialize the argument info vectors */\nargs[0] = &ffitypecomplexfloat;\nargs[1] = &ffitypecomplexdouble;\nargs[2] = &ffitypecomplexlongdouble;\nvalues[0] = &cf;\nvalues[1] = &cd;\nvalues[2] = &cld;\n\n/* Initialize the cif */\nif (ffiprepcif(&cif, FFIDEFAULTABI, 3,\n&ffitypevoid, args) == FFIOK)\n{\ncf = 1.0 + 20.0 * I;\ncd = 300.0 + 4000.0 * I;\ncld = 50000.0 + 600000.0 * I;\n/* Call the function */\nfficall(&cif, (void (*)(void))complexfn, 0, values);\n}\n\nreturn 0;\n}\n\nThis is an example for defining a custom complex type descriptor for\ncompilers that support them:\n\n/*\n* This macro can be used to define new complex type descriptors\n* in a platform independent way.\n*\n* name: Name of the new descriptor is ffitypecomplex<name>.\n* type: The C base type of the complex type.\n*/\n#define FFICOMPLEXTYPEDEF(name, type, ffitype)             \\\nstatic ffitype *ffielementscomplex##name [2] = {      \\\n(ffitype *)(&ffitype), NULL                             \\\n};                                                        \\\nstruct structaligncomplex##name {                      \\\nchar c;                                                  \\\nComplex type x;                                         \\\n};                                                        \\\nffitype ffitypecomplex##name = {                      \\\nsizeof(Complex type),                                   \\\noffsetof(struct structaligncomplex##name, x),         \\\nFFITYPECOMPLEX,                                        \\\n(ffitype )ffielementscomplex##name                 \\\n}\n\n/* Define new complex type descriptors using the macro: */\n/* ffitypecomplexsint */\nFFICOMPLEXTYPEDEF(sint, int, ffitypesint);\n/* ffitypecomplexuchar */\nFFICOMPLEXTYPEDEF(uchar, unsigned char, ffitypeuint8);\n\nThe new type descriptors can then be used like one of the built-in\ntype descriptors in the previous example.\n\nFile: libffi.info,  Node: Multiple ABIs,  Next: The Closure API,  Prev: Types,  Up: Using libffi\n"
                    },
                    {
                        "name": "2.4 Multiple ABIs",
                        "content": "A given platform may provide multiple different ABIs at once.  For\ninstance, the x86 platform has both 'stdcall' and 'fastcall' functions.\n\n'libffi' provides some support for this.  However, this is\nnecessarily platform-specific.\n\nFile: libffi.info,  Node: The Closure API,  Next: Closure Example,  Prev: Multiple ABIs,  Up: Using libffi\n"
                    },
                    {
                        "name": "2.5 The Closure API",
                        "content": "'libffi' also provides a way to write a generic function - a function\nthat can accept and decode any combination of arguments.  This can be\nuseful when writing an interpreter, or to provide wrappers for arbitrary\nfunctions.\n\nThis facility is called the \"closure API\". Closures are not supported\non all platforms; you can check the 'FFICLOSURES' define to determine\nwhether they are supported on the current platform.\n\nBecause closures work by assembling a tiny function at runtime, they\nrequire special allocation on platforms that have a non-executable heap.\nMemory management for closures is handled by a pair of functions:\n\n-- Function: void *fficlosurealloc (sizet SIZE, void CODE)\nAllocate a chunk of memory holding SIZE bytes.  This returns a\npointer to the writable address, and sets *CODE to the\ncorresponding executable address.\n\nSIZE should be sufficient to hold a 'fficlosure' object.\n\n-- Function: void fficlosurefree (void *WRITABLE)\nFree memory allocated using 'fficlosurealloc'.  The argument is\nthe writable address that was returned.\n\nOnce you have allocated the memory for a closure, you must construct\na 'fficif' describing the function call.  Finally you can prepare the\nclosure function:\n\n-- Function: ffistatus ffiprepclosureloc (fficlosure *CLOSURE,\nfficif *CIF, void (*FUN) (fficif *CIF, void *RET, void\nARGS, void *USERDATA), void *USERDATA, void *CODELOC)\nPrepare a closure function.  The arguments to\n'ffiprepclosureloc' are:\n\nCLOSURE\nThe address of a 'fficlosure' object; this is the writable\naddress returned by 'fficlosurealloc'.\n\nCIF\nThe 'fficif' describing the function parameters.  Note that\nthis object, and the types to which it refers, must be kept\nalive until the closure itself is freed.\n\nUSERDATA\nAn arbitrary datum that is passed, uninterpreted, to your\nclosure function.\n\nCODELOC\nThe executable address returned by 'fficlosurealloc'.\n\nFUN\nThe function which will be called when the closure is invoked.\nIt is called with the arguments:\n\nCIF\nThe 'fficif' passed to 'ffiprepclosureloc'.\n\nRET\nA pointer to the memory used for the function's return\nvalue.\n\nIf the function is declared as returning 'void', then\nthis value is garbage and should not be used.\n\nOtherwise, FUN must fill the object to which this points,\nfollowing the same special promotion behavior as\n'fficall'.  That is, in most cases, RET points to an\nobject of exactly the size of the type specified when CIF\nwas constructed.  However, integral types narrower than\nthe system register size are widened.  In these cases\nyour program may assume that RET points to an 'ffiarg'\nobject.\n\nARGS\nA vector of pointers to memory holding the arguments to\nthe function.\n\nUSERDATA\nThe same USERDATA that was passed to\n'ffiprepclosureloc'.\n\n'ffiprepclosureloc' will return 'FFIOK' if everything went ok,\nand one of the other 'ffistatus' values on error.\n\nAfter calling 'ffiprepclosureloc', you can cast CODELOC to the\nappropriate pointer-to-function type.\n\nYou may see old code referring to 'ffiprepclosure'.  This function\nis deprecated, as it cannot handle the need for separate writable and\nexecutable addresses.\n\nFile: libffi.info,  Node: Closure Example,  Next: Thread Safety,  Prev: The Closure API,  Up: Using libffi\n"
                    },
                    {
                        "name": "2.6 Closure Example",
                        "content": "A trivial example that creates a new 'puts' by binding 'fputs' with\n'stdout'.\n\n#include <stdio.h>\n#include <ffi.h>\n\n/* Acts like puts with the file given at time of enclosure. */\nvoid putsbinding(fficif *cif, void *ret, void* args[],\nvoid *stream)\n{\n*(ffiarg *)ret = fputs(*(char )args[0], (FILE *)stream);\n}\n\ntypedef int (*putst)(char *);\n\nint main()\n{\nfficif cif;\nffitype *args[1];\nfficlosure *closure;\n\nvoid *boundputs;\nint rc;\n\n/* Allocate closure and boundputs */\nclosure = fficlosurealloc(sizeof(fficlosure), &boundputs);\n\nif (closure)\n{\n/* Initialize the argument info vectors */\nargs[0] = &ffitypepointer;\n\n/* Initialize the cif */\nif (ffiprepcif(&cif, FFIDEFAULTABI, 1,\n&ffitypesint, args) == FFIOK)\n{\n/* Initialize the closure, setting stream to stdout */\nif (ffiprepclosureloc(closure, &cif, putsbinding,\nstdout, boundputs) == FFIOK)\n{\nrc = ((putst)boundputs)(\"Hello World!\");\n/* rc now holds the result of the call to fputs */\n}\n}\n}\n\n/* Deallocate both closure, and boundputs */\nfficlosurefree(closure);\n\nreturn 0;\n}\n\n\nFile: libffi.info,  Node: Thread Safety,  Prev: Closure Example,  Up: Using libffi\n"
                    },
                    {
                        "name": "2.7 Thread Safety",
                        "content": "'libffi' is not completely thread-safe.  However, many parts are, and if\nyou follow some simple rules, you can use it safely in a multi-threaded\nprogram.\n\n* 'ffiprepcif' may modify the 'ffitype' objects passed to it.  It\nis best to ensure that only a single thread prepares a given\n'fficif' at a time.\n\n* On some platforms, 'ffiprepcif' may modify the size and alignment\nof some types, depending on the chosen ABI. On these platforms, if\nyou switch between ABIs, you must ensure that there is only one\ncall to 'ffiprepcif' at a time.\n\nCurrently the only affected platform is PowerPC and the only\naffected type is 'long double'.\n\nFile: libffi.info,  Node: Memory Usage,  Next: Missing Features,  Prev: Using libffi,  Up: Top\n"
                    }
                ]
            },
            "3 Memory Usage": {
                "content": "Note that memory allocated by 'fficlosurealloc' and freed by\n'fficlosurefree' does not come from the same general pool of memory\nthat 'malloc' and 'free' use.  To accomodate security settings, 'libffi'\nmay aquire memory, for example, by mapping temporary files into multiple\nplaces in the address space (once to write out the closure, a second to\nexecute it).  The search follows this list, using the first that works:\n\n* A anonymous mapping (i.e.  not file-backed)\n\n* 'memfdcreate()', if the kernel supports it.\n\n* A file created in the directory referenced by the environment\nvariable 'LIBFFITMPDIR'.\n\n* Likewise for the environment variable 'TMPDIR'.\n\n* A file created in '/tmp'.\n\n* A file created in '/var/tmp'.\n\n* A file created in '/dev/shm'.\n\n* A file created in the user's home directory ('$HOME').\n\n* A file created in any directory listed in '/etc/mtab'.\n\n* A file created in any directory listed in '/proc/mounts'.\n\nIf security settings prohibit using any of these for closures,\n'fficlosurealloc' will fail.\n\nFile: libffi.info,  Node: Missing Features,  Next: Index,  Prev: Memory Usage,  Up: Top\n",
                "subsections": []
            },
            "4 Missing Features": {
                "content": "'libffi' is missing a few features.  We welcome patches to add support\nfor these.\n\n* Variadic closures.\n\n* There is no support for bit fields in structures.\n\n* The \"raw\" API is undocumented.\n\n* The Go API is undocumented.\n\nFile: libffi.info,  Node: Index,  Prev: Missing Features,  Up: Top\n",
                "subsections": []
            },
            "Index": {
                "content": "* Menu:\n\n* ABI:                                   Introduction.         (line 13)\n* Application Binary Interface:          Introduction.         (line 13)\n* calling convention:                    Introduction.         (line 13)\n* cif:                                   The Basics.           (line 14)\n* closure API:                           The Closure API.      (line 13)\n* closures:                              The Closure API.      (line 13)\n* FFI:                                   Introduction.         (line 31)\n* fficall:                              The Basics.           (line 72)\n* FFICLOSURES:                          The Closure API.      (line 13)\n* fficlosurealloc:                     The Closure API.      (line 19)\n* fficlosurefree:                      The Closure API.      (line 26)\n* ffigetstructoffsets:                Size and Alignment.   (line 39)\n* ffiprepcif:                          The Basics.           (line 16)\n* ffiprepcifvar:                      The Basics.           (line 39)\n* ffiprepclosureloc:                  The Closure API.      (line 34)\n* ffistatus:                            The Basics.           (line 16)\n* ffistatus <1>:                        The Basics.           (line 39)\n* ffistatus <2>:                        Size and Alignment.   (line 39)\n* ffistatus <3>:                        The Closure API.      (line 34)\n* ffitype:                              Structures.           (line 10)\n* ffitype <1>:                          Structures.           (line 10)\n* ffitype <2>:                          Complex.              (line 15)\n* ffitype <3>:                          Complex.              (line 15)\n* ffitypecomplexdouble:               Primitive Types.      (line 82)\n* ffitypecomplexfloat:                Primitive Types.      (line 79)\n* ffitypecomplexlongdouble:           Primitive Types.      (line 85)\n* ffitypedouble:                       Primitive Types.      (line 41)\n* ffitypefloat:                        Primitive Types.      (line 38)\n* ffitypelongdouble:                   Primitive Types.      (line 71)\n* ffitypepointer:                      Primitive Types.      (line 75)\n* ffitypeschar:                        Primitive Types.      (line 47)\n* ffitypesint:                         Primitive Types.      (line 62)\n* ffitypesint16:                       Primitive Types.      (line 23)\n* ffitypesint32:                       Primitive Types.      (line 29)\n* ffitypesint64:                       Primitive Types.      (line 35)\n* ffitypesint8:                        Primitive Types.      (line 17)\n* ffitypeslong:                        Primitive Types.      (line 68)\n* ffitypesshort:                       Primitive Types.      (line 56)\n* ffitypeuchar:                        Primitive Types.      (line 44)\n* ffitypeuint:                         Primitive Types.      (line 59)\n* ffitypeuint16:                       Primitive Types.      (line 20)\n* ffitypeuint32:                       Primitive Types.      (line 26)\n* ffitypeuint64:                       Primitive Types.      (line 32)\n* ffitypeuint8:                        Primitive Types.      (line 14)\n* ffitypeulong:                        Primitive Types.      (line 65)\n* ffitypeushort:                       Primitive Types.      (line 53)\n* ffitypevoid:                         Primitive Types.      (line 10)\n* Foreign Function Interface:            Introduction.         (line 31)\n* void:                                  The Basics.           (line 72)\n* void <1>:                              The Closure API.      (line 19)\n* void <2>:                              The Closure API.      (line 26)\n\n",
                "subsections": []
            }
        }
    }
}