diff --git a/tutorials/scripting/gdextension/gdextension_interface_json_file.rst b/tutorials/scripting/gdextension/gdextension_interface_json_file.rst new file mode 100644 index 00000000000..85184bfc2bf --- /dev/null +++ b/tutorials/scripting/gdextension/gdextension_interface_json_file.rst @@ -0,0 +1,344 @@ +.. _doc_gdextension_interface_json_file: + +The gdextension_interface.json file +=================================== + +The ``gdextension_interface.json`` file is the canonical definition of the C API that +Godot uses to communicate with GDExtensions. + +You can use the Godot executable to dump the file by using the following command: + +.. code-block:: shell + + godot --headless --dump-gdextension-interface-json + +This file is intended to be used by GDExtension language bindings to generate code for +using this API in whatever form makes the most sense for that language. + +For languages that can be extended via C, or provide tools for interacting with C code, +it's also possible to use the Godot executable to dump a generated C header file: + +.. code-block:: shell + + godot --headless --dump-gdextension-interface + +.. note:: + + The header file is compatible with earlier versions of the header file that were included + with Godot 4.5 and earlier, which means it preserves some type-o's in names in order to + ensure compatibility. These "legacy names" can be found in the ``legacy_type_name`` key + in the JSON file. + +The goal of this page is to explain the JSON format for the GDExtension language bindings that +would like to do their own code generation from the JSON. + +Overall structure +----------------- + +The JSON file is broken up into 3 sections: + +- The header, which includes some miscellaneous information at the top-level of the JSON file. +- The ``types`` key, which defines all the types used in the GDExtension interface. +- The ``interface`` key, which defines all the function pointers that can be loaded via + ``GDExtensionInterfaceGetProcAddress`` function pointer, which is passed to all GDExtensions + when they are loaded. + +There is a complete `JSON schema `__ +included in Godot's source code. + +Even though we may add a little bit to this file with each minor release of Godot, we strive +to **never** change anything in a backwards incompatible way, or remove anything. Every type +and interface function is labeled with the version of Godot it was introduce in (the ``since`` +key), so you can always use the latest version of the file, and simply refrain from using +anything in versions of Godot that are newer than the version you are targeting. + +Header +------ + +The "header" is made up of 3 miscellaneous keys at the top-level of the file: + +- ``_copyright``: The standard copyright and license text that Godot includes in all source + code files. +- ``$schema``: Points to the JSON schema relative to this file (it can be useful to place + the schema in the same directory, if you're viewing it with a code editor that understands + JSON schema). +- ``format_version``: An integer for the version of the file format. Right now, there is + only one format version (``1``), if we ever change the file format in an incompatible way, + we will increment this number. This this *doesn't* reflect the version of the data (so it + won't change between Godot versions), only the format of the file. Hopefully, we'll never + have to use it, but it allows code generators to error early if they encounter an unexpected + value here. + +Types +----- + +The "types" section is an array of types that will be used by other types, and the interface +functions that will be in the last section. + +The types should be evaluated in order. Later types may refer to earlier types, but earlier +types will not refer to later types. + +There is a small set of built-in types which aren't explicitly listed in the JSON: + +- ``void`` +- ``int8_t`` +- ``uint8_t`` +- ``int16_t`` +- ``uint16_t`` +- ``int32_t`` +- ``uint32_t`` +- ``int64_t`` +- ``uint64_t`` +- ``size_t`` +- ``char`` +- ``char16_t`` +- ``char32_t`` +- ``wchar_t`` +- ``float`` +- ``double`` + +These correspond to their equivalent C types. + +Additionally, types can include modifiers such as: + +- ``*`` (ex ``int8_t*``) to indicate a pointer to the type +- ``const`` (ex ``const int8_t*``) to indicate a const type + +Each type defined in the JSON file falls into one of 5 "kind"s: + +- ``enum`` +- ``handle`` +- ``alias`` +- ``struct`` +- ``function`` + +Regardless of the "kind", all types can have the following keys: + +- ``name``: The name of the type, which could be used as a valid C identifier. +- ``description``: An array of strings documenting the type, where each string is a line of + documentation (this format for ``description`` is used through out the JSON file). +- ``since``: The Godot version that introduced this type. +- ``deprecated``: An object with its own keys for the Godot version the type was deprecated in + (``since``), a message explaining the deprecation (``message``) and optionally a replacement + to use instead (``replacement``). + +Enums +~~~~~ + +Enums are 32-bit integers with a fixed set of possible values. In C, they could be represented +as an ``enum``. + +They have the following keys: + +- ``is_bitfield``: If true, this enum is a bitfield, where the enum values can be bitwise OR'd together. + It is false by default. +- ``values``: The array of fixed values for this enum, each with a ``name``, ``value`` and ``description``. + +An enum should be represented as an ``int32_t``, unless ``is_bitfield`` is true, in which case a ``uint32_t`` +should be used. + +Example ++++++++ + +.. code-block:: json + + { + "name": "GDExtensionInitializationLevel", + "kind": "enum", + "values": [ + { + "name": "GDEXTENSION_INITIALIZATION_CORE", + "value": 0 + }, + { + "name": "GDEXTENSION_INITIALIZATION_SERVERS", + "value": 1 + }, + { + "name": "GDEXTENSION_INITIALIZATION_SCENE", + "value": 2 + }, + { + "name": "GDEXTENSION_INITIALIZATION_EDITOR", + "value": 3 + }, + { + "name": "GDEXTENSION_MAX_INITIALIZATION_LEVEL", + "value": 4 + } + ] + } + +Handles +~~~~~~~ + +Handles are pointers to opaque structs. In C, they could be represented as ``void *`` or ``struct{} *``. + +They have the following keys: + +- ``is_const``: If true, this handle type is to be treated as a "const pointer", meaning it's internal + data will not be changed. It is false by default. +- ``is_uninitialized``: If true, this handle type is to be treated as pointing to uninitialized memory + (which may be initialized using interface functions). +- ``parent``: The optional name of another handle type, if this handle type is the const or uninitialized + version of the parent type. + +Handles are the size of pointers on the given architecture (so, 64-bit on x86_64 and 32-bit on x86_32, +for example). + +Example ++++++++ + +.. code-block:: json + + { + "name": "GDExtensionStringNamePtr", + "kind": "handle" + } + +Aliases +~~~~~~~ + +Aliases are alternative names for another type. In C, they could be represented with a ``typedef``. + +They have only one additional key: + +- ``type``: The type the alias is an alternative name for. It may include modifiers as described above. + +These should be represented using the same C type as the type they point to, except when a pointer +modifier is used (in which case, they should be represented as pointers). + +Example ++++++++ + +.. code-block:: json + + { + "name": "GDExtensionInt", + "kind": "alias", + "type": "int64_t" + } + +Structs +~~~~~~~ + +Structs represent C ``struct``'s (aka a block of memory made up the given members in order), and should +follow all the same layout and alignment rules as C structs. + +They have only one additional key: + +- ``members``: An array of objects which have a ``name``, ``type`` (which may include modifiers) and + ``description``. + +Example ++++++++ + +.. code-block:: json + + { + "name": "GDExtensionCallError", + "kind": "struct", + "members": [ + { + "name": "error", + "type": "GDExtensionCallErrorType" + }, + { + "name": "argument", + "type": "int32_t" + }, + { + "name": "expected", + "type": "int32_t" + } + ] + } + +Functions +~~~~~~~~~ + +Functions represent C function pointer types, with a list of arguments and a return type, and should +follow the same size and alignment requirements as C function pointers. + +They have the following members: + +- ``return_value``: An object which has a ``type`` (which may include modifiers), and description. + It will always be given, and use ``void`` as the ``type`` if the function returns no value. +- ``arguments``: An array of function arguments which each has a ``type`` (which may include modifiers), + a ``name`` and ``description``. + + +Example ++++++++ + +.. code-block:: json + + { + "name": "GDExtensionPtrConstructor", + "kind": "function", + "return_value": { + "type": "void" + }, + "arguments": [ + { + "name": "p_base", + "type": "GDExtensionUninitializedTypePtr" + }, + { + "name": "p_args", + "type": "const GDExtensionConstTypePtr*" + } + ] + } + +Interface +--------- + +The final section of the JSON file is the list of interface functions, which can be loaded by their +``name`` using the ``GDExtensionInterfaceGetProcAddress`` function pointer, which is passed to all +GDExtensions when they are loaded. + +They have some of the same keys as types, including ``name``, ``since``, ``deprecated``, and +``description``. + +And they also have ``return_value`` and ``arguments`` that have the same format as the keys of the +same name on function types, as described in the previous section. + +There are only a handful of unique, miscellaneous fields: + +- ``see``: An array of strings describing external references with more information, for example, + names of classes or functions in the Godot source code, or URLs pointing to documentation. +- ``legacy_type_name``: The legacy name used for the function pointer type in the header generated + by Godot, when the original name used in the didn't match the pattern used for these type names. + The field only exists so that we can generate the header in a way that is backwards compatible + with the header from Godot 4.5 or earlier, and it shouldn't be used unless you also need to + maintain compatibility with the old header. + +Example +~~~~~~~ + +.. code-block:: json + + { + "name": "get_godot_version", + "return_value": { + "type": "void" + }, + "arguments": [ + { + "name": "r_godot_version", + "type": "GDExtensionGodotVersion*", + "description": [ + "A pointer to the structure to write the version information into." + ] + } + ], + "description": [ + "Gets the Godot version that the GDExtension was loaded into." + ], + "since": "4.1", + "deprecated": { + "since": "4.5", + "replace_with": "get_godot_version2" + } + } diff --git a/tutorials/scripting/gdextension/index.rst b/tutorials/scripting/gdextension/index.rst index 76be9d8690b..13b0f8e54fd 100644 --- a/tutorials/scripting/gdextension/index.rst +++ b/tutorials/scripting/gdextension/index.rst @@ -24,3 +24,4 @@ articles instead, such as the articles about :ref:`C++ (godot-cpp)