Automatically generated GDExtension bindings for C/C++
This is not meant to be a replacement for the godot-cpp project,
but rather an alternative for those who want the full API matching extension_api.json
in a C-compatible interface,
for example for creating bindings for other programming languages.
- Easily embeddable in any project: include gdextension-lite.h, compile and link gdextension-lite-one.c and you're good to go
- Automatically generated from
extension_api.json
file, so new Godot APIs are added in a matter of regenerating the bindings - Bindings for all Godot classes, variant types, methods, operators, utility functions, enums, GDExtension interface functions
- Extra constructors with C strings for
String
,StringName
,NodePath
,Color
,godot_int
andgodot_float
GDCLEANUP
macro for declaring variables with automatic cleanup in C (compiler needs to support__attribute__((cleanup(...)))
, like GCC and clang)- Supports Godot 4.1+
- Faster compilation time than godot-cpp project
- Generate the bindings files (needs Python 3.10+):
make generate-bindings
- Implement your extension in C/C++:
// @file my-extension.c // 1. Include gdextension-lite.h: the whole API is accessible through it #include <gdextension-lite/gdextension-lite.h> void initialize(void *userdata, GDExtensionInitializationLevel p_level); void deinitialize(void *userdata, GDExtensionInitializationLevel p_level); // 2. In your GDExtension entrypoint, call `gdextension_lite_initialize` GDExtensionBool gdextension_entry( GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization ) { gdextension_lite_initialize(p_get_proc_address); // setup initialize/deinitialize as usual r_initialization->initialize = &initialize; r_initialization->deinitialize = &deinitialize; // return success as usual return 1; } // 3. Use the bindings freely void initialize(void *userdata, GDExtensionInitializationLevel p_level) { if (p_level != GDEXTENSION_INITIALIZATION_SCENE) { return; } // print("Hello from GDExtension Lite!") { godot_String msg = godot_new_String_with_latin1_chars("Hello from GDExtension Lite!"); godot_Variant msg_var = godot_new_Variant_with_String(&msg); godot_print(&msg_var, NULL, 0); // As always in C, you are responsible for freeing objects godot_Variant_destroy(&msg_var); godot_String_destroy(&msg); } // prints("OS.get_name() ==", OS.get_name()) { // Use "GDCLEANUP(godot_TYPE)" for automatic variable cleanup at the end of scope // (compiler needs to support `__attribute__((cleanup(...)))`, like GCC and clang) GDCLEANUP(godot_String) msg = godot_new_String_with_latin1_chars("OS.get_name() =="); GDCLEANUP(godot_Variant) msg_var = godot_new_Variant_with_String(&msg); // Objects are always used via pointers, no need for cleanup // You may need to reference/unreference RefCounted instances, though godot_OS *os = godot_OS_singleton(); GDCLEANUP(godot_String) os_name = godot_OS_get_name(os); GDCLEANUP(godot_Variant) os_name_var = godot_new_Variant_with_String(&os_name); const godot_Variant *args[] = { &os_name_var }; godot_prints(&msg_var, args, 1); } // var node = Node() // print(node) // node.free() { godot_Node *node = godot_new_Node(); GDCLEANUP(godot_String) node_name = godot_Object_to_string((godot_Object *) node); GDCLEANUP(godot_Variant) node_name_var = godot_new_Variant_with_String(&node_name); godot_print(&node_name_var, NULL, 0); godot_object_destroy(node); } } void deinitialize(void *userdata, GDExtensionInitializationLevel p_level) { // no-op }
- Now compile
gdextension-lite-one.c
and link it to your own code. Example SConstruct:We recommend compilingSharedLibrary( [ 'my-extension.c', 'path-to-gdextension-lite/gdextension-lite/gdextension-lite-one.c', ], CFLAGS=["-O2", "-flto"], )
gdextension-lite-one.c
with-O2 -flto
flags to avoid linking all Godot functions, but rather link only the ones you actually use.
Sample code is also available at the sample folder.
- Every type and function binding from Godot have the prefix
godot_
- Every GDExtension Lite function have the prefix
gdextension_lite_
- Constructors have the format
godot_new_<type name>
orgodot_new_<type name>_with_<arg1 type>_<arg2 type>...
- Destructors have the format
godot_<type name>_destroy
- Member getters have the format
godot_<type name>_get_<member name>
- Member setters have the format
godot_<type name>_set_<member name>
- Indexed getters have the format
godot_<type name>_indexed_get
- Indexed setters have the format
godot_<type name>_indexed_set
- Keyed getters have the format
godot_<type name>_keyed_get
- Keyed setters have the format
godot_<type name>_keyed_set
- Operators have the format
godot_<type name>_op_<operator name>
for unary operators andgodot_<type name>_op_<operator name>_<right-hand side type>
for binary operators - Methods have the format
godot_<type name>_<method name>
- Enumerators defined by classes have the format
godot_<type name>_<enum name>
- Godot utility functions have the format
godot_<function name>
- Variadic methods and utility functions expect argv/argc parameters
- Singleton getters have the format
godot_<type name>_singleton
- Update the
extension_api.json
andgdextension_interface.h
files (depends on Godot 4 executable):make refresh-gdextension-api
- Generate the bindings files (depends on Python 3.10+):
make generate-bindings
- Generate the distribution
build/gdextension-lite.zip
file with all headers:make dist