gdnative-c-example.rst 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. .. _doc_gdnative_c_example:
  2. GDNative C example
  3. ==================
  4. Introduction
  5. ------------
  6. This tutorial will introduce you to the bare minimum required to create GDNative
  7. modules. This should be your starting point into the world of GDNative.
  8. Understanding the contents of this tutorial will help you in understanding all
  9. that is to come after this.
  10. Before we begin, you can download the source code to the example object we
  11. describe below in the `GDNative-demos repository
  12. <https://github.com/GodotNativeTools/GDNative-demos/tree/master/c/SimpleDemo>`_.
  13. This example project also contains a SConstruct file that makes compiling a
  14. little easier, but in this tutorial we'll be doing things by hand to
  15. understand the process.
  16. :ref:`GDNative <class_GDNative>` can be used to create several types of
  17. additions to Godot, using interfaces such as
  18. :ref:`PluginScript <class_PluginScript>` or
  19. :ref:`ARVRInterfaceGDNative <class_ARVRInterfaceGDNative>`. In this tutorial we
  20. are going to look at creating a :ref:`NativeScript <class_NativeScript>`
  21. module. NativeScript allows you to write logic in C or C++ in a similar fashion
  22. as you would write a GDScript file. We'll be creating the C equivalent of this
  23. GDScript:
  24. ::
  25. extends Reference
  26. var data
  27. func _ready():
  28. data = "World from GDScript!"
  29. func get_data():
  30. return data
  31. Future tutorials will focus on the other types of GDNative modules and explain
  32. when and how to use each of them.
  33. Prerequisites
  34. -------------
  35. Before we start you'll need a few things:
  36. 1) A Godot executable for your target version.
  37. 2) A C compiler. On Linux, install ``gcc`` or ``clang`` from your package
  38. manager. On macOS, you can install Xcode from the Mac App Store. On Windows,
  39. you can use Visual Studio 2015 or later, or MinGW-w64.
  40. 3) A Git clone of the `godot_headers
  41. repository <https://github.com/GodotNativeTools/godot_headers>`_: these are
  42. the C headers for Godot's public API exposed to GDNative.
  43. For the latter, we suggest that you create a dedicated folder for this GDNative
  44. example project, open a terminal in that folder and execute:
  45. .. code-block:: none
  46. git clone https://github.com/GodotNativeTools/godot_headers
  47. This will download the required files into that folder.
  48. .. tip::
  49. If you plan to use Git for your GDNative project, you can also add
  50. ``godot_headers`` as a Git submodule.
  51. .. note::
  52. The ``godot_headers`` repository has different branches. As Godot evolves,
  53. so does GDNative. While we try to preserve compatibility between version,
  54. you should always build your GDNative module against headers matching the
  55. Godot stable branch (e.g. ``3.1``) and ideally actual release (e.g.
  56. ``3.1.1-stable``) that you use.
  57. GDNative modules built against older versions of the Godot headers *may*
  58. work with newer versions of the engine, but not the other way around.
  59. The ``master`` branch of the ``godot_headers`` repository is kept in line with
  60. the ``master`` branch of Godot and thus contains the GDNative class and
  61. structure definitions that will work with the latest development builds.
  62. If you want to write a GDNative module for a stable version of Godot, look at
  63. the available Git tags (with ``git tags``) for the one matching your engine
  64. version. In the ``godot_headers`` repository, such tags are prefixed with
  65. ``godot-``, so you can e.g. checkout the ``godot-3.1.1-stable`` tag for use with
  66. Godot 3.1.1. In your cloned repository, you can do:
  67. .. code-block:: none
  68. git checkout godot-3.1.1-stable
  69. If a tag matching your stable release is missing for any reason, you can fall
  70. back to the matching stable branch (e.g. ``3.1``), which you would also check
  71. out with ``git checkout 3.1``.
  72. If you are building Godot from source with your own changes that impact
  73. GDNative, you can find the updated class and structure definition in
  74. ``<godotsource>/modules/gdnative/include``
  75. Our C source
  76. ------------
  77. Let's start by writing our main code. Eventually, we want to end up with a file
  78. structure that looks along those lines:
  79. .. code-block:: none
  80. + <your development folder>
  81. + godot_headers
  82. - <lots of files here>
  83. + simple
  84. + bin
  85. - libsimple.dll/so/dylib
  86. - libsimple.gdnlib
  87. - simple.gdns
  88. + src
  89. - .gdignore
  90. - simple.c
  91. main.tscn
  92. project.godot
  93. Open up Godot and create a new project called "simple" alongside your
  94. ``godot_headers`` Git clone. This will create the ``simple`` folder and
  95. ``project.godot`` file. Then manually create ``bin`` and ``src`` subfolders in
  96. this folder.
  97. We're going to start by having a look at what our ``simple.c`` file contains.
  98. Now, for our example here we're making a single C source file without a header
  99. to keep things simple. Once you start writing bigger projects it is advisable
  100. to break your project up into multiple files. That however falls outside of the
  101. scope of this tutorial.
  102. We'll be looking at the source code bit by bit so all the parts below should all
  103. be put together into one big file. Each section will be explained as we add it.
  104. .. code-block:: C
  105. #include <gdnative_api_struct.gen.h>
  106. #include <string.h>
  107. const godot_gdnative_core_api_struct *api = NULL;
  108. const godot_gdnative_ext_nativescript_api_struct *nativescript_api = NULL;
  109. The above code includes the GDNative API struct header and a standard header
  110. that we will use further down for string operations.
  111. It then defines two pointers to two different structs. GDNative supports a large
  112. collection of functions for calling back into the main Godot executable. In
  113. order for your module to have access to these functions, GDNative provides your
  114. application with a struct containing pointers to all these functions.
  115. To keep this implementation modular and easily extendable, the core functions
  116. are available directly through the "core" API struct, but additional functions
  117. have their own "GDNative structs" that are accessible through extensions.
  118. In our example, we access one of these extension to gain access to the functions
  119. specifically needed for NativeScript.
  120. A NativeScript behaves like any other script in Godot. Because the NativeScript
  121. API is rather low level, it requires the library to specify many things more
  122. verbosely than other scripting systems, such as GDScript. When a NativeScript
  123. instance gets created, a library-given constructor gets called. When that
  124. instance gets destroyed, the given destructor will be executed.
  125. .. code-block:: C
  126. void *simple_constructor(godot_object *p_instance, void *p_method_data);
  127. void simple_destructor(godot_object *p_instance, void *p_method_data, void *p_user_data);
  128. godot_variant simple_get_data(godot_object *p_instance, void *p_method_data,
  129. void *p_user_data, int p_num_args, godot_variant **p_args);
  130. These are forward declarations for the functions we'll be implementing for our
  131. object. A constructor and destructor is needed. Additionally, the object will
  132. have a single method called ``get_data``.
  133. Next up is the first of the entry points Godot will call when our dynamic
  134. library is loaded. These methods are all prefixed with ``godot_`` (you can
  135. change this later on) followed by their name. ``gdnative_init`` is a function
  136. that initializes our dynamic library. Godot will give it a pointer to a
  137. structure that contains various bits of information we may find useful among
  138. which the pointers to our API structures.
  139. For any additional API structures we need to loop through our extensions array
  140. and check the type of extension.
  141. .. code-block:: C
  142. void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *p_options) {
  143. api = p_options->api_struct;
  144. // Now find our extensions.
  145. for (int i = 0; i < api->num_extensions; i++) {
  146. switch (api->extensions[i]->type) {
  147. case GDNATIVE_EXT_NATIVESCRIPT: {
  148. nativescript_api = (godot_gdnative_ext_nativescript_api_struct *)api->extensions[i];
  149. }; break;
  150. default: break;
  151. }
  152. }
  153. }
  154. Next up is ``gdnative_terminate`` which is called before the library is
  155. unloaded. Godot will unload the library when no object uses it anymore. Here,
  156. you can do any cleanup you may need to do. For our example, we're simply going
  157. to clear our API pointers.
  158. .. code-block:: C
  159. void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *p_options) {
  160. api = NULL;
  161. nativescript_api = NULL;
  162. }
  163. Finally we have ``nativescript_init`` which is the most important function we'll
  164. need today. This function will be called by Godot as part of loading a GDNative
  165. library and communicates back to the engine what objects we make available.
  166. .. code-block:: C
  167. void GDN_EXPORT godot_nativescript_init(void *p_handle) {
  168. godot_instance_create_func create = { NULL, NULL, NULL };
  169. create.create_func = &simple_constructor;
  170. godot_instance_destroy_func destroy = { NULL, NULL, NULL };
  171. destroy.destroy_func = &simple_destructor;
  172. nativescript_api->godot_nativescript_register_class(p_handle, "Simple", "Reference",
  173. create, destroy);
  174. godot_instance_method get_data = { NULL, NULL, NULL };
  175. get_data.method = &simple_get_data;
  176. godot_method_attributes attributes = { GODOT_METHOD_RPC_MODE_DISABLED };
  177. nativescript_api->godot_nativescript_register_method(p_handle, "Simple", "get_data",
  178. attributes, get_data);
  179. }
  180. We first tell the engine which classes are implemented by calling
  181. ``nativescript_register_class``. The first parameter here is the handle pointer
  182. given to us. The second is the name of our object class. The third is the type
  183. of object in Godot that we 'inherit' from; this is not true inheritance but it's
  184. close enough. Finally, our fourth and fifth parameters are descriptions for our
  185. constructor and destructor.
  186. We then tell Godot about our methods (well our one method in this case), by
  187. calling ``nativescript_register_method`` for each method of our class. In our
  188. case, that is just ``get_data``. Our first parameter is yet again our handle
  189. pointer. The second is again the name of the object class we're registering. The
  190. third is the name of our function as it will be known to GDScript. The fourth is
  191. our attributes setting (see ``godot_method_rpc_mode`` enum in
  192. ``godot_headers/nativescript/godot_nativescript.h`` for possible values). The
  193. fifth and final parameter is a description of which function to call when the
  194. method gets called.
  195. The description struct ``instance_method`` contains the function pointer to the
  196. function itself as first field. The other two fields in these structs are for
  197. specifying per-method userdata. The second is the ``method_data`` field which is
  198. passed on every function call as the ``p_method_data`` argument. This is useful
  199. to reuse one function for different methods on possibly multiple different
  200. script-classes. If the ``method_data`` value is a pointer to memory that needs
  201. to be freed, the third ``free_func`` field can contain a pointer to a function
  202. that will free that memory. That free function gets called when the script
  203. itself (not instance!) gets unloaded (so usually at library-unload time).
  204. Now, it's time to start working on the functions of our object. First, we define
  205. a structure that we use to store the member data of an instance of our GDNative
  206. class.
  207. .. code-block:: C
  208. typedef struct user_data_struct {
  209. char data[256];
  210. } user_data_struct;
  211. And then, we define our constructor. All we do in our constructor is allocate
  212. memory for our structure and fill it with some data. Note that we use Godot's
  213. memory functions so the memory gets tracked and then return the pointer to our
  214. new structure. This pointer will act as our instance identifier in case multiple
  215. objects are instantiated.
  216. This pointer will be passed to any of our functions related to our object as a
  217. parameter called ``p_user_data``, and can both be used to identify our instance
  218. and to access its member data.
  219. .. code-block:: C
  220. void *simple_constructor(godot_object *p_instance, void *p_method_data) {
  221. user_data_struct *user_data = api->godot_alloc(sizeof(user_data_struct));
  222. strcpy(user_data->data, "World from GDNative!");
  223. return user_data;
  224. }
  225. Our destructor is called when Godot is done with our object and we free our
  226. instances' member data.
  227. .. code-block:: C
  228. void simple_destructor(godot_object *p_instance, void *p_method_data, void *p_user_data) {
  229. api->godot_free(p_user_data);
  230. }
  231. And finally, we implement our ``get_data`` function. Data is always sent and
  232. returned as variants so in order to return our data, which is a string, we first
  233. need to convert our C string to a Godot string object, and then copy that string
  234. object into the variant we are returning.
  235. .. code-block:: C
  236. godot_variant simple_get_data(godot_object *p_instance, void *p_method_data,
  237. void *p_user_data, int p_num_args, godot_variant **p_args) {
  238. godot_string data;
  239. godot_variant ret;
  240. user_data_struct *user_data = (user_data_struct *)p_user_data;
  241. api->godot_string_new(&data);
  242. api->godot_string_parse_utf8(&data, user_data->data);
  243. api->godot_variant_new_string(&ret, &data);
  244. api->godot_string_destroy(&data);
  245. return ret;
  246. }
  247. Strings are heap-allocated in Godot, so they have a destructor which frees the
  248. memory. Destructors are named ``godot_TYPENAME_destroy``. When a Variant gets
  249. created with a String, it references the String. That means that the original
  250. String can be "destroyed" to decrease the ref-count. If that does not happen the
  251. String memory will leak since the ref-count will never be zero and the memory
  252. never deallocated. The returned variant gets automatically destroyed by Godot.
  253. .. note::
  254. In more complex operations it can be confusing the keep track of which value
  255. needs to be deallocated and which does not. As a general rule: call
  256. ``godot_TYPENAME_destroy`` when a C++ destructor would be called instead.
  257. The String destructor would be called in C++ after the Variant was created,
  258. so the same is necessary in C.
  259. The variant we return is destroyed automatically by Godot.
  260. And that is the whole source code of our module.
  261. Compiling
  262. ---------
  263. We now need to compile our source code. As mentioned our example project on
  264. GitHub contains a SCons configuration that does all the hard work for you, but
  265. for our tutorial here we are going to call the compilers directly.
  266. Assuming you are sticking to the folder structure suggested above, it is best to
  267. open a terminal session in the ``src`` folder and execute the commands from
  268. there. Make sure to create the ``bin`` folder before you proceed.
  269. On Linux:
  270. .. code-block:: none
  271. gcc -std=c11 -fPIC -c -I../../godot_headers simple.c -o simple.os
  272. gcc -shared simple.os -o ../bin/libsimple.so
  273. On macOS:
  274. .. code-block:: none
  275. clang -std=c11 -fPIC -c -I../../godot_headers simple.c -o simple.os
  276. clang -dynamiclib simple.os -o ../bin/libsimple.dylib
  277. On Windows:
  278. .. code-block:: none
  279. cl /Fosimple.obj /c simple.c /nologo -EHsc -DNDEBUG /MD /I. /I..\..\godot_headers
  280. link /nologo /dll /out:..\bin\libsimple.dll /implib:..\bin\libsimple.lib simple.obj
  281. .. note::
  282. On the Windows build you also end up with a ``libsimple.lib`` library. This
  283. is a library that you can compile into a project to provide access to the
  284. DLL. We get it as a byproduct and we do not need it :)
  285. When exporting your game for release this file will be ignored.
  286. .. tip::
  287. If you add a blank ``.gdignore`` file to the ``src`` folder, Godot will not
  288. try to import the compiler-generated files. This is necessary on Windows
  289. were compiled objects have the ``.obj`` extension, which is also a 3D model
  290. format supported by the engine.
  291. Creating the GDNativeLibrary (``.gdnlib``) file
  292. -----------------------------------------------
  293. With our module compiled, we now need to create a corresponding
  294. :ref:`GDNativeLibrary <class_GDNativeLibrary>` resource with ``.gdnlib``
  295. extension which we place alongside our dynamic libraries. This file tells Godot
  296. what dynamic libraries are part of our module and need to be loaded per
  297. platform.
  298. We can use Godot to generate this file, so open the "simple" project in the
  299. editor.
  300. Start by clicking the create resource button in the Inspector:
  301. .. image:: img/new_resource.gif
  302. And select ``GDNativeLibrary``:
  303. .. image:: img/gdnativelibrary_resource.png
  304. You should see a contextual editor appear in the bottom panel. Use the "Expand
  305. Bottom Panel" button in the bottom right to expand it to full height:
  306. .. image:: img/gdnativelibrary_editor.png
  307. General properties
  308. ~~~~~~~~~~~~~~~~~~
  309. In the Inspector, you have various properties to control loading the library.
  310. If *Load Once* is enabled, our library is loaded only once and each individual
  311. script that uses our library will use the same data. Any variable you define
  312. globally will be accessible from any instance of your object you create. If
  313. *Load Once* is disabled, a new copy of the library is loaded into memory each
  314. time a script accesses the library.
  315. If *Singleton* is enabled, our library is automatically loaded and a function
  316. called ``godot_singleton_init`` is called. We'll leave that for another
  317. tutorial.
  318. The *Symbol Prefix* is a prefix for our core functions, such as ``godot_`` in
  319. ``godot_nativescript_init`` seen earlier. If you use multiple GDNative libraries
  320. that you wish to statically link, you will have to use different prefixes. This
  321. again is a subject to dive into deeper in a separate tutorial, it is only needed
  322. at this time for deployment to iOS as this platform does not like dynamic
  323. libraries.
  324. *Reloadable* defines whether the library should be reloaded when the editor
  325. loses and gains focus, typically to pick up new or modified symbols from any
  326. change made to the library externally.
  327. Platform libraries
  328. ~~~~~~~~~~~~~~~~~~
  329. The GDNativeLibrary editor plugin lets you configure two things for each
  330. platform and architecture that you aim to support.
  331. The *Dynamic Library* column (``entry`` section in the saved file) tells us for
  332. each platform and feature combination which dynamic library has to be loaded.
  333. This also informs the exporter which files need to be exported when exporting to
  334. a specific platform.
  335. The *Dependencies* column (also ``dependencies`` section) tells Godot what other
  336. files need to be exported for each platform in order for our library to work.
  337. Say that your GDNative module uses another DLL to implement functionality from a
  338. 3rd party library, this is where you list that DLL.
  339. For our example, we only built libraries for Linux, macOS and/or Windows, so you
  340. can link them in the relevant fields by clicking the folder button. If you built
  341. all three libraries, you should have something like this:
  342. .. image:: img/gdnativelibrary_complete.png
  343. Saving the resource
  344. ~~~~~~~~~~~~~~~~~~~
  345. We can then save our GDNativeLibrary resource as ``bin/libsimple.gdnlib`` with
  346. the Save button in the Inspector:
  347. .. image:: img/gdnativelibrary_save.png
  348. The file is saved in a text-based format and should have contents similar to
  349. this:
  350. .. code-block:: none
  351. [general]
  352. singleton=false
  353. load_once=true
  354. symbol_prefix="godot_"
  355. reloadable=true
  356. [entry]
  357. OSX.64="res://bin/libsimple.dylib"
  358. OSX.32="res://bin/libsimple.dylib"
  359. Windows.64="res://bin/libsimple.dll"
  360. X11.64="res://bin/libsimple.so"
  361. [dependencies]
  362. OSX.64=[ ]
  363. OSX.32=[ ]
  364. Windows.64=[ ]
  365. X11.64=[ ]
  366. Creating the NativeScript (``.gdns``) file
  367. ------------------------------------------
  368. With our ``.gdnlib`` file we've told Godot how to load our library, now we need
  369. to tell it about our "Simple" object class. We do this by creating a
  370. :ref:`NativeScript <class_NativeScript>` resource file with ``.gdns`` extension.
  371. Like done for the GDNativeLibrary resource, click the button to create a new
  372. resource in the Inspector and select ``NativeScript``:
  373. .. image:: img/nativescript_resource.png
  374. The inspector will show a few properties that we need to fill. As *Class Name*
  375. we enter "Simple" which is the object class name that we declared in our C
  376. source when calling ``godot_nativescript_register_class``. We also need to
  377. select our ``.gdnlib`` file by clicking on *Library* and selecting *Load*:
  378. .. image:: img/nativescript_library.png
  379. Finally click on the save icon and save this as ``bin/simple.gdns``:
  380. .. image:: img/save_gdns.gif
  381. Now it's time to build our scene. Add a Control node to your scene as your root
  382. and call it ``main``. Then add a Button and a Label as child nodes. Place them
  383. somewhere nice on screen and give your button a name.
  384. .. image:: img/c_main_scene_layout.png
  385. Select the control node and attach a script to it:
  386. .. image:: img/add_main_script.gif
  387. Next link up the ``pressed`` signal on the button to your script:
  388. .. image:: img/connect_button_signal.gif
  389. Don't forget to save your scene, call it ``main.tscn``.
  390. Now we can implement our ``main.gd`` code:
  391. ::
  392. extends Control
  393. # load the Simple library
  394. onready var data = preload("res://bin/simple.gdns").new()
  395. func _on_Button_pressed():
  396. $Label.text = "Data = " + data.get_data()
  397. After all that, our project should work. The first time you run it Godot will
  398. ask you what your main scene is and you select your ``main.tscn`` file and
  399. presto:
  400. .. image:: img/c_sample_result.png