koffi 2.1.0-beta.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/ChangeLog.md +2 -1
  2. package/build/qemu/2.1.0/koffi_darwin_arm64.tar.gz +0 -0
  3. package/build/qemu/2.1.0/koffi_darwin_x64.tar.gz +0 -0
  4. package/build/qemu/2.1.0/koffi_freebsd_arm64.tar.gz +0 -0
  5. package/build/qemu/2.1.0/koffi_freebsd_ia32.tar.gz +0 -0
  6. package/build/qemu/2.1.0/koffi_freebsd_x64.tar.gz +0 -0
  7. package/build/qemu/2.1.0/koffi_linux_arm32hf.tar.gz +0 -0
  8. package/build/qemu/2.1.0/koffi_linux_arm64.tar.gz +0 -0
  9. package/build/qemu/2.1.0/koffi_linux_ia32.tar.gz +0 -0
  10. package/build/qemu/2.1.0/koffi_linux_riscv64hf64.tar.gz +0 -0
  11. package/build/qemu/2.1.0/koffi_linux_x64.tar.gz +0 -0
  12. package/build/qemu/2.1.0/koffi_openbsd_ia32.tar.gz +0 -0
  13. package/build/qemu/2.1.0/koffi_openbsd_x64.tar.gz +0 -0
  14. package/build/qemu/2.1.0/koffi_win32_arm64.tar.gz +0 -0
  15. package/build/qemu/2.1.0/koffi_win32_ia32.tar.gz +0 -0
  16. package/build/qemu/2.1.0/koffi_win32_x64.tar.gz +0 -0
  17. package/doc/benchmarks.md +14 -14
  18. package/doc/benchmarks.xlsx +0 -0
  19. package/doc/index.rst +2 -2
  20. package/doc/static/perf_linux_20220812.png +0 -0
  21. package/doc/static/perf_windows_20220812.png +0 -0
  22. package/doc/types.md +10 -12
  23. package/package.json +2 -2
  24. package/qemu/registry/machines.json +2 -2
  25. package/qemu/registry/sha256sum.txt +2 -2
  26. package/src/abi_arm32.cc +23 -55
  27. package/src/abi_arm64.cc +22 -54
  28. package/src/abi_riscv64.cc +20 -52
  29. package/src/abi_x64_sysv.cc +20 -52
  30. package/src/abi_x64_win.cc +20 -52
  31. package/src/abi_x86.cc +24 -56
  32. package/src/call.cc +117 -143
  33. package/src/call.hh +4 -4
  34. package/src/ffi.cc +16 -4
  35. package/src/util.hh +0 -20
  36. package/test/callbacks.js +3 -3
  37. package/test/misc.c +2 -2
  38. package/test/sync.js +2 -2
  39. package/vendor/libcc/libcc.cc +75 -55
  40. package/vendor/libcc/libcc.hh +306 -255
  41. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.NativeActivity/raylib_android.NativeActivity.vcxproj +226 -0
  42. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.NativeActivity/raylib_android.NativeActivity.vcxproj.filters +10 -0
  43. package/vendor/raylib/projects/VS2019-Android/raylib_android/raylib_android.NativeActivity/raylib_android.NativeActivity.vcxproj.user +4 -0
  44. package/vendor/raylib/projects/VS2019-Android/raylib_android.sln +75 -0
  45. package/vendor/raylib/projects/VS2022/examples/audio_module_playing.vcxproj +390 -0
  46. package/vendor/raylib/projects/VS2022/examples/audio_multichannel_sound.vcxproj +390 -0
  47. package/vendor/raylib/projects/VS2022/examples/audio_music_stream.vcxproj +390 -0
  48. package/vendor/raylib/projects/VS2022/examples/audio_raw_stream.vcxproj +390 -0
  49. package/vendor/raylib/projects/VS2022/examples/audio_sound_loading.vcxproj +390 -0
  50. package/vendor/raylib/projects/VS2022/examples/audio_stream_effects.vcxproj +390 -0
  51. package/vendor/raylib/projects/VS2022/examples/core_2d_camera.vcxproj +390 -0
  52. package/vendor/raylib/projects/VS2022/examples/core_2d_camera_mouse_zoom.vcxproj +390 -0
  53. package/vendor/raylib/projects/VS2022/examples/core_2d_camera_platformer.vcxproj +390 -0
  54. package/vendor/raylib/projects/VS2022/examples/core_3d_camera_first_person.vcxproj +390 -0
  55. package/vendor/raylib/projects/VS2022/examples/core_3d_camera_free.vcxproj +390 -0
  56. package/vendor/raylib/projects/VS2022/examples/core_3d_camera_mode.vcxproj +390 -0
  57. package/vendor/raylib/projects/VS2022/examples/core_3d_picking.vcxproj +390 -0
  58. package/vendor/raylib/projects/VS2022/examples/core_basic_screen_manager.vcxproj +390 -0
  59. package/vendor/raylib/projects/VS2022/examples/core_basic_window.vcxproj +390 -0
  60. package/vendor/raylib/projects/VS2022/examples/core_custom_frame_control.vcxproj +390 -0
  61. package/vendor/raylib/projects/VS2022/examples/core_custom_logging.vcxproj +390 -0
  62. package/vendor/raylib/projects/VS2022/examples/core_drop_files.vcxproj +390 -0
  63. package/vendor/raylib/projects/VS2022/examples/core_input_gamepad.vcxproj +387 -0
  64. package/vendor/raylib/projects/VS2022/examples/core_input_gestures.vcxproj +387 -0
  65. package/vendor/raylib/projects/VS2022/examples/core_input_keys.vcxproj +387 -0
  66. package/vendor/raylib/projects/VS2022/examples/core_input_mouse.vcxproj +387 -0
  67. package/vendor/raylib/projects/VS2022/examples/core_input_mouse_wheel.vcxproj +387 -0
  68. package/vendor/raylib/projects/VS2022/examples/core_input_multitouch.vcxproj +387 -0
  69. package/vendor/raylib/projects/VS2022/examples/core_loading_thread.vcxproj +387 -0
  70. package/vendor/raylib/projects/VS2022/examples/core_random_values.vcxproj +387 -0
  71. package/vendor/raylib/projects/VS2022/examples/core_scissor_test.vcxproj +387 -0
  72. package/vendor/raylib/projects/VS2022/examples/core_split_screen.vcxproj +387 -0
  73. package/vendor/raylib/projects/VS2022/examples/core_storage_values.vcxproj +387 -0
  74. package/vendor/raylib/projects/VS2022/examples/core_vr_simulator.vcxproj +387 -0
  75. package/vendor/raylib/projects/VS2022/examples/core_window_flags.vcxproj +387 -0
  76. package/vendor/raylib/projects/VS2022/examples/core_window_letterbox.vcxproj +387 -0
  77. package/vendor/raylib/projects/VS2022/examples/core_window_should_close.vcxproj +390 -0
  78. package/vendor/raylib/projects/VS2022/examples/core_world_screen.vcxproj +387 -0
  79. package/vendor/raylib/projects/VS2022/examples/easings_testbed.vcxproj +387 -0
  80. package/vendor/raylib/projects/VS2022/examples/embedded_files_loading.vcxproj +387 -0
  81. package/vendor/raylib/projects/VS2022/examples/models_animation.vcxproj +387 -0
  82. package/vendor/raylib/projects/VS2022/examples/models_billboard.vcxproj +387 -0
  83. package/vendor/raylib/projects/VS2022/examples/models_box_collisions.vcxproj +387 -0
  84. package/vendor/raylib/projects/VS2022/examples/models_cubicmap.vcxproj +387 -0
  85. package/vendor/raylib/projects/VS2022/examples/models_first_person_maze.vcxproj +387 -0
  86. package/vendor/raylib/projects/VS2022/examples/models_geometric_shapes.vcxproj +387 -0
  87. package/vendor/raylib/projects/VS2022/examples/models_heightmap.vcxproj +387 -0
  88. package/vendor/raylib/projects/VS2022/examples/models_loading.vcxproj +387 -0
  89. package/vendor/raylib/projects/VS2022/examples/models_loading_gltf.vcxproj +387 -0
  90. package/vendor/raylib/projects/VS2022/examples/models_loading_vox.vcxproj +387 -0
  91. package/vendor/raylib/projects/VS2022/examples/models_mesh_generation.vcxproj +387 -0
  92. package/vendor/raylib/projects/VS2022/examples/models_mesh_picking.vcxproj +387 -0
  93. package/vendor/raylib/projects/VS2022/examples/models_orthographic_projection.vcxproj +387 -0
  94. package/vendor/raylib/projects/VS2022/examples/models_rlgl_solar_system.vcxproj +387 -0
  95. package/vendor/raylib/projects/VS2022/examples/models_skybox.vcxproj +387 -0
  96. package/vendor/raylib/projects/VS2022/examples/models_waving_cubes.vcxproj +387 -0
  97. package/vendor/raylib/projects/VS2022/examples/models_yaw_pitch_roll.vcxproj +387 -0
  98. package/vendor/raylib/projects/VS2022/examples/rlgl_compute_shaders.vcxproj +391 -0
  99. package/vendor/raylib/projects/VS2022/examples/rlgl_standalone.vcxproj +391 -0
  100. package/vendor/raylib/projects/VS2022/examples/shaders_basic_lighting.vcxproj +387 -0
  101. package/vendor/raylib/projects/VS2022/examples/shaders_custom_uniform.vcxproj +387 -0
  102. package/vendor/raylib/projects/VS2022/examples/shaders_eratosthenes.vcxproj +387 -0
  103. package/vendor/raylib/projects/VS2022/examples/shaders_fog.vcxproj +387 -0
  104. package/vendor/raylib/projects/VS2022/examples/shaders_hot_reloading.vcxproj +387 -0
  105. package/vendor/raylib/projects/VS2022/examples/shaders_julia_set.vcxproj +387 -0
  106. package/vendor/raylib/projects/VS2022/examples/shaders_mesh_instancing.vcxproj +387 -0
  107. package/vendor/raylib/projects/VS2022/examples/shaders_model_shader.vcxproj +387 -0
  108. package/vendor/raylib/projects/VS2022/examples/shaders_multi_sample2d.vcxproj +387 -0
  109. package/vendor/raylib/projects/VS2022/examples/shaders_palette_switch.vcxproj +387 -0
  110. package/vendor/raylib/projects/VS2022/examples/shaders_postprocessing.vcxproj +387 -0
  111. package/vendor/raylib/projects/VS2022/examples/shaders_raymarching.vcxproj +387 -0
  112. package/vendor/raylib/projects/VS2022/examples/shaders_shapes_textures.vcxproj +387 -0
  113. package/vendor/raylib/projects/VS2022/examples/shaders_simple_mask.vcxproj +387 -0
  114. package/vendor/raylib/projects/VS2022/examples/shaders_spotlight.vcxproj +387 -0
  115. package/vendor/raylib/projects/VS2022/examples/shaders_texture_drawing.vcxproj +387 -0
  116. package/vendor/raylib/projects/VS2022/examples/shaders_texture_waves.vcxproj +387 -0
  117. package/vendor/raylib/projects/VS2022/examples/shapes_basic_shapes.vcxproj +387 -0
  118. package/vendor/raylib/projects/VS2022/examples/shapes_bouncing_ball.vcxproj +387 -0
  119. package/vendor/raylib/projects/VS2022/examples/shapes_collision_area.vcxproj +387 -0
  120. package/vendor/raylib/projects/VS2022/examples/shapes_colors_palette.vcxproj +387 -0
  121. package/vendor/raylib/projects/VS2022/examples/shapes_draw_circle_sector.vcxproj +387 -0
  122. package/vendor/raylib/projects/VS2022/examples/shapes_draw_rectangle_rounded.vcxproj +387 -0
  123. package/vendor/raylib/projects/VS2022/examples/shapes_draw_ring.vcxproj +387 -0
  124. package/vendor/raylib/projects/VS2022/examples/shapes_easings_ball_anim.vcxproj +387 -0
  125. package/vendor/raylib/projects/VS2022/examples/shapes_easings_box_anim.vcxproj +387 -0
  126. package/vendor/raylib/projects/VS2022/examples/shapes_easings_rectangle_array.vcxproj +387 -0
  127. package/vendor/raylib/projects/VS2022/examples/shapes_following_eyes.vcxproj +387 -0
  128. package/vendor/raylib/projects/VS2022/examples/shapes_lines_bezier.vcxproj +387 -0
  129. package/vendor/raylib/projects/VS2022/examples/shapes_logo_raylib.vcxproj +387 -0
  130. package/vendor/raylib/projects/VS2022/examples/shapes_logo_raylib_anim.vcxproj +387 -0
  131. package/vendor/raylib/projects/VS2022/examples/shapes_rectangle_scaling.vcxproj +387 -0
  132. package/vendor/raylib/projects/VS2022/examples/text_codepoints_loading.vcxproj +387 -0
  133. package/vendor/raylib/projects/VS2022/examples/text_draw_3d.vcxproj +387 -0
  134. package/vendor/raylib/projects/VS2022/examples/text_font_filters.vcxproj +387 -0
  135. package/vendor/raylib/projects/VS2022/examples/text_font_loading.vcxproj +387 -0
  136. package/vendor/raylib/projects/VS2022/examples/text_font_sdf.vcxproj +387 -0
  137. package/vendor/raylib/projects/VS2022/examples/text_font_spritefont.vcxproj +387 -0
  138. package/vendor/raylib/projects/VS2022/examples/text_format_text.vcxproj +387 -0
  139. package/vendor/raylib/projects/VS2022/examples/text_input_box.vcxproj +387 -0
  140. package/vendor/raylib/projects/VS2022/examples/text_raylib_fonts.vcxproj +387 -0
  141. package/vendor/raylib/projects/VS2022/examples/text_rectangle_bounds.vcxproj +387 -0
  142. package/vendor/raylib/projects/VS2022/examples/text_unicode.vcxproj +387 -0
  143. package/vendor/raylib/projects/VS2022/examples/text_writing_anim.vcxproj +387 -0
  144. package/vendor/raylib/projects/VS2022/examples/textures_background_scrolling.vcxproj +387 -0
  145. package/vendor/raylib/projects/VS2022/examples/textures_blend_modes.vcxproj +387 -0
  146. package/vendor/raylib/projects/VS2022/examples/textures_bunnymark.vcxproj +387 -0
  147. package/vendor/raylib/projects/VS2022/examples/textures_draw_tiled.vcxproj +387 -0
  148. package/vendor/raylib/projects/VS2022/examples/textures_fog_of_war.vcxproj +387 -0
  149. package/vendor/raylib/projects/VS2022/examples/textures_gif_player.vcxproj +387 -0
  150. package/vendor/raylib/projects/VS2022/examples/textures_image_drawing.vcxproj +387 -0
  151. package/vendor/raylib/projects/VS2022/examples/textures_image_generation.vcxproj +387 -0
  152. package/vendor/raylib/projects/VS2022/examples/textures_image_loading.vcxproj +387 -0
  153. package/vendor/raylib/projects/VS2022/examples/textures_image_processing.vcxproj +387 -0
  154. package/vendor/raylib/projects/VS2022/examples/textures_image_text.vcxproj +387 -0
  155. package/vendor/raylib/projects/VS2022/examples/textures_logo_raylib.vcxproj +387 -0
  156. package/vendor/raylib/projects/VS2022/examples/textures_mouse_painting.vcxproj +387 -0
  157. package/vendor/raylib/projects/VS2022/examples/textures_npatch_drawing.vcxproj +387 -0
  158. package/vendor/raylib/projects/VS2022/examples/textures_particles_blending.vcxproj +387 -0
  159. package/vendor/raylib/projects/VS2022/examples/textures_polygon.vcxproj +387 -0
  160. package/vendor/raylib/projects/VS2022/examples/textures_raw_data.vcxproj +387 -0
  161. package/vendor/raylib/projects/VS2022/examples/textures_sprite_anim.vcxproj +387 -0
  162. package/vendor/raylib/projects/VS2022/examples/textures_sprite_button.vcxproj +387 -0
  163. package/vendor/raylib/projects/VS2022/examples/textures_sprite_explosion.vcxproj +387 -0
  164. package/vendor/raylib/projects/VS2022/examples/textures_srcrec_dstrec.vcxproj +387 -0
  165. package/vendor/raylib/projects/VS2022/examples/textures_to_image.vcxproj +387 -0
  166. package/vendor/raylib/projects/VS2022/raylib/raylib.vcxproj +340 -0
  167. package/vendor/raylib/projects/VS2022/raylib.sln +2347 -0
  168. package/build/qemu/2.1.0-beta.3/koffi_darwin_arm64.tar.gz +0 -0
  169. package/build/qemu/2.1.0-beta.3/koffi_darwin_x64.tar.gz +0 -0
  170. package/build/qemu/2.1.0-beta.3/koffi_freebsd_arm64.tar.gz +0 -0
  171. package/build/qemu/2.1.0-beta.3/koffi_freebsd_ia32.tar.gz +0 -0
  172. package/build/qemu/2.1.0-beta.3/koffi_freebsd_x64.tar.gz +0 -0
  173. package/build/qemu/2.1.0-beta.3/koffi_linux_arm32hf.tar.gz +0 -0
  174. package/build/qemu/2.1.0-beta.3/koffi_linux_arm64.tar.gz +0 -0
  175. package/build/qemu/2.1.0-beta.3/koffi_linux_ia32.tar.gz +0 -0
  176. package/build/qemu/2.1.0-beta.3/koffi_linux_riscv64hf64.tar.gz +0 -0
  177. package/build/qemu/2.1.0-beta.3/koffi_linux_x64.tar.gz +0 -0
  178. package/build/qemu/2.1.0-beta.3/koffi_openbsd_ia32.tar.gz +0 -0
  179. package/build/qemu/2.1.0-beta.3/koffi_openbsd_x64.tar.gz +0 -0
  180. package/build/qemu/2.1.0-beta.3/koffi_win32_arm64.tar.gz +0 -0
  181. package/build/qemu/2.1.0-beta.3/koffi_win32_ia32.tar.gz +0 -0
  182. package/build/qemu/2.1.0-beta.3/koffi_win32_x64.tar.gz +0 -0
  183. package/doc/dist/doctrees/benchmarks.doctree +0 -0
  184. package/doc/dist/doctrees/changes.doctree +0 -0
  185. package/doc/dist/doctrees/contribute.doctree +0 -0
  186. package/doc/dist/doctrees/environment.pickle +0 -0
  187. package/doc/dist/doctrees/functions.doctree +0 -0
  188. package/doc/dist/doctrees/index.doctree +0 -0
  189. package/doc/dist/doctrees/memory.doctree +0 -0
  190. package/doc/dist/doctrees/platforms.doctree +0 -0
  191. package/doc/dist/doctrees/start.doctree +0 -0
  192. package/doc/dist/doctrees/types.doctree +0 -0
  193. package/doc/dist/html/.buildinfo +0 -4
  194. package/doc/dist/html/_sources/benchmarks.md.txt +0 -137
  195. package/doc/dist/html/_sources/changes.md.txt +0 -161
  196. package/doc/dist/html/_sources/contribute.md.txt +0 -127
  197. package/doc/dist/html/_sources/functions.md.txt +0 -421
  198. package/doc/dist/html/_sources/index.rst.txt +0 -39
  199. package/doc/dist/html/_sources/memory.md.txt +0 -32
  200. package/doc/dist/html/_sources/platforms.md.txt +0 -31
  201. package/doc/dist/html/_sources/start.md.txt +0 -100
  202. package/doc/dist/html/_sources/types.md.txt +0 -541
  203. package/doc/dist/html/_static/_sphinx_javascript_frameworks_compat.js +0 -134
  204. package/doc/dist/html/_static/basic.css +0 -932
  205. package/doc/dist/html/_static/bench_linux.png +0 -0
  206. package/doc/dist/html/_static/bench_windows.png +0 -0
  207. package/doc/dist/html/_static/custom.css +0 -22
  208. package/doc/dist/html/_static/debug.css +0 -69
  209. package/doc/dist/html/_static/doctools.js +0 -264
  210. package/doc/dist/html/_static/documentation_options.js +0 -14
  211. package/doc/dist/html/_static/file.png +0 -0
  212. package/doc/dist/html/_static/jquery-3.6.0.js +0 -10881
  213. package/doc/dist/html/_static/jquery.js +0 -2
  214. package/doc/dist/html/_static/language_data.js +0 -199
  215. package/doc/dist/html/_static/minus.png +0 -0
  216. package/doc/dist/html/_static/perf_linux_20220623.png +0 -0
  217. package/doc/dist/html/_static/perf_linux_20220623_2.png +0 -0
  218. package/doc/dist/html/_static/perf_linux_20220627.png +0 -0
  219. package/doc/dist/html/_static/perf_linux_20220628.png +0 -0
  220. package/doc/dist/html/_static/perf_windows_20220623.png +0 -0
  221. package/doc/dist/html/_static/perf_windows_20220623_2.png +0 -0
  222. package/doc/dist/html/_static/perf_windows_20220627.png +0 -0
  223. package/doc/dist/html/_static/perf_windows_20220628.png +0 -0
  224. package/doc/dist/html/_static/plus.png +0 -0
  225. package/doc/dist/html/_static/pygments.css +0 -252
  226. package/doc/dist/html/_static/scripts/furo-extensions.js +0 -0
  227. package/doc/dist/html/_static/scripts/furo.js +0 -3
  228. package/doc/dist/html/_static/scripts/furo.js.LICENSE.txt +0 -7
  229. package/doc/dist/html/_static/scripts/furo.js.map +0 -1
  230. package/doc/dist/html/_static/searchtools.js +0 -531
  231. package/doc/dist/html/_static/skeleton.css +0 -296
  232. package/doc/dist/html/_static/styles/furo-extensions.css +0 -2
  233. package/doc/dist/html/_static/styles/furo-extensions.css.map +0 -1
  234. package/doc/dist/html/_static/styles/furo.css +0 -2
  235. package/doc/dist/html/_static/styles/furo.css.map +0 -1
  236. package/doc/dist/html/_static/underscore-1.13.1.js +0 -2042
  237. package/doc/dist/html/_static/underscore.js +0 -6
  238. package/doc/dist/html/benchmarks.html +0 -571
  239. package/doc/dist/html/changes.html +0 -686
  240. package/doc/dist/html/contribute.html +0 -403
  241. package/doc/dist/html/functions.html +0 -718
  242. package/doc/dist/html/genindex.html +0 -253
  243. package/doc/dist/html/index.html +0 -359
  244. package/doc/dist/html/memory.html +0 -346
  245. package/doc/dist/html/objects.inv +0 -0
  246. package/doc/dist/html/platforms.html +0 -371
  247. package/doc/dist/html/search.html +0 -261
  248. package/doc/dist/html/searchindex.js +0 -1
  249. package/doc/dist/html/start.html +0 -384
  250. package/doc/dist/html/types.html +0 -1061
@@ -1,1061 +0,0 @@
1
- <!doctype html>
2
- <html class="no-js" lang="en">
3
- <head><meta charset="utf-8"/>
4
- <meta name="viewport" content="width=device-width,initial-scale=1"/>
5
- <meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
6
- <link rel="index" title="Index" href="genindex" /><link rel="search" title="Search" href="search" /><link rel="next" title="Functions" href="functions" /><link rel="prev" title="Quick start" href="start" />
7
-
8
- <meta name="generator" content="sphinx-5.0.1, furo 2022.06.04.1"/>
9
- <title>Data types - Koffi</title>
10
- <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
11
- <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=40978830699223671f4072448e654b5958f38b89" />
12
- <link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
13
- <link rel="stylesheet" type="text/css" href="_static/custom.css" />
14
-
15
-
16
-
17
-
18
- <style>
19
- body {
20
- --color-code-background: #f8f8f8;
21
- --color-code-foreground: black;
22
- --color-brand-primary: #FF6600;
23
- --color-brand-content: #FF6600;
24
-
25
- }
26
- @media not print {
27
- body[data-theme="dark"] {
28
- --color-code-background: #202020;
29
- --color-code-foreground: #d0d0d0;
30
- --color-brand-primary: #FF6600;
31
- --color-brand-content: #FF6600;
32
-
33
- }
34
- @media (prefers-color-scheme: dark) {
35
- body:not([data-theme="light"]) {
36
- --color-code-background: #202020;
37
- --color-code-foreground: #d0d0d0;
38
- --color-brand-primary: #FF6600;
39
- --color-brand-content: #FF6600;
40
-
41
- }
42
- }
43
- }
44
- </style></head>
45
- <body>
46
-
47
- <script>
48
- document.body.dataset.theme = localStorage.getItem("theme") || "auto";
49
- </script>
50
-
51
-
52
- <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
53
- <symbol id="svg-toc" viewBox="0 0 24 24">
54
- <title>Contents</title>
55
- <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
56
- <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
57
- </svg>
58
- </symbol>
59
- <symbol id="svg-menu" viewBox="0 0 24 24">
60
- <title>Menu</title>
61
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
62
- stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
63
- <line x1="3" y1="12" x2="21" y2="12"></line>
64
- <line x1="3" y1="6" x2="21" y2="6"></line>
65
- <line x1="3" y1="18" x2="21" y2="18"></line>
66
- </svg>
67
- </symbol>
68
- <symbol id="svg-arrow-right" viewBox="0 0 24 24">
69
- <title>Expand</title>
70
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
71
- stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
72
- <polyline points="9 18 15 12 9 6"></polyline>
73
- </svg>
74
- </symbol>
75
- <symbol id="svg-sun" viewBox="0 0 24 24">
76
- <title>Light mode</title>
77
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
78
- stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
79
- <circle cx="12" cy="12" r="5"></circle>
80
- <line x1="12" y1="1" x2="12" y2="3"></line>
81
- <line x1="12" y1="21" x2="12" y2="23"></line>
82
- <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
83
- <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
84
- <line x1="1" y1="12" x2="3" y2="12"></line>
85
- <line x1="21" y1="12" x2="23" y2="12"></line>
86
- <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
87
- <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
88
- </svg>
89
- </symbol>
90
- <symbol id="svg-moon" viewBox="0 0 24 24">
91
- <title>Dark mode</title>
92
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
93
- stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
94
- <path stroke="none" d="M0 0h24v24H0z" fill="none" />
95
- <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
96
- </svg>
97
- </symbol>
98
- <symbol id="svg-sun-half" viewBox="0 0 24 24">
99
- <title>Auto light/dark mode</title>
100
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
101
- stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-shadow">
102
- <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
103
- <circle cx="12" cy="12" r="9" />
104
- <path d="M13 12h5" />
105
- <path d="M13 15h4" />
106
- <path d="M13 18h1" />
107
- <path d="M13 9h4" />
108
- <path d="M13 6h1" />
109
- </svg>
110
- </symbol>
111
- </svg>
112
-
113
- <input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
114
- <input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc">
115
- <label class="overlay sidebar-overlay" for="__navigation">
116
- <div class="visually-hidden">Hide navigation sidebar</div>
117
- </label>
118
- <label class="overlay toc-overlay" for="__toc">
119
- <div class="visually-hidden">Hide table of contents sidebar</div>
120
- </label>
121
-
122
-
123
-
124
- <div class="page">
125
- <header class="mobile-header">
126
- <div class="header-left">
127
- <label class="nav-overlay-icon" for="__navigation">
128
- <div class="visually-hidden">Toggle site navigation sidebar</div>
129
- <i class="icon"><svg><use href="#svg-menu"></use></svg></i>
130
- </label>
131
- </div>
132
- <div class="header-center">
133
- <a href="index"><div class="brand">Koffi</div></a>
134
- </div>
135
- <div class="header-right">
136
- <div class="theme-toggle-container theme-toggle-header">
137
- <button class="theme-toggle">
138
- <div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
139
- <svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
140
- <svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
141
- <svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
142
- </button>
143
- </div>
144
- <label class="toc-overlay-icon toc-header-icon" for="__toc">
145
- <div class="visually-hidden">Toggle table of contents sidebar</div>
146
- <i class="icon"><svg><use href="#svg-toc"></use></svg></i>
147
- </label>
148
- </div>
149
- </header>
150
- <aside class="sidebar-drawer">
151
- <div class="sidebar-container">
152
-
153
- <div class="sidebar-sticky"><a class="sidebar-brand" href="index">
154
-
155
-
156
- <span class="sidebar-brand-text">Koffi</span>
157
-
158
- </a><form class="sidebar-search-container" method="get" action="search" role="search">
159
- <input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
160
- <input type="hidden" name="check_keywords" value="yes">
161
- <input type="hidden" name="area" value="default">
162
- </form>
163
- <div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
164
- <ul class="current">
165
- <li class="toctree-l1"><a class="reference internal" href="platforms">Requirements</a></li>
166
- <li class="toctree-l1"><a class="reference internal" href="start">Quick start</a></li>
167
- <li class="toctree-l1 current current-page"><a class="current reference internal" href="#">Data types</a></li>
168
- <li class="toctree-l1"><a class="reference internal" href="functions">Functions</a></li>
169
- <li class="toctree-l1"><a class="reference internal" href="memory">Memory usage</a></li>
170
- <li class="toctree-l1"><a class="reference internal" href="benchmarks">Benchmarks</a></li>
171
- <li class="toctree-l1"><a class="reference internal" href="contribute">Contributing</a></li>
172
- <li class="toctree-l1"><a class="reference internal" href="changes">Changelog</a></li>
173
- </ul>
174
-
175
- </div>
176
- <div style="text-align: center; margin-top: 2em;">
177
- <a href="https://www.npmjs.com/package/koffi"><img src="https://img.shields.io/badge/NPM-2.O.1-brightgreen" alt="NPM"/></a>
178
- <a href="https://github.com/Koromix/luigi/tree/master/koffi"><img src="https://img.shields.io/badge/GitHub-Koffi-ff6600" alt="GitHub"/></a>
179
- </div></div>
180
-
181
- </div>
182
-
183
- </div>
184
- </aside>
185
- <div class="main">
186
- <div class="content">
187
- <div class="article-container">
188
- <a href="#" class="back-to-top muted-link">
189
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
190
- <path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
191
- </svg>
192
- <span>Back to top</span>
193
- </a>
194
- <div class="content-icon-container">
195
- <div class="theme-toggle-container theme-toggle-content">
196
- <button class="theme-toggle">
197
- <div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
198
- <svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
199
- <svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
200
- <svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
201
- </button>
202
- </div>
203
- <label class="toc-overlay-icon toc-content-icon" for="__toc">
204
- <div class="visually-hidden">Toggle table of contents sidebar</div>
205
- <i class="icon"><svg><use href="#svg-toc"></use></svg></i>
206
- </label>
207
- </div>
208
- <article role="main">
209
- <section id="data-types">
210
- <h1>Data types<a class="headerlink" href="#data-types" title="Permalink to this heading">#</a></h1>
211
- <section id="primitive-types">
212
- <h2>Primitive types<a class="headerlink" href="#primitive-types" title="Permalink to this heading">#</a></h2>
213
- <section id="standard-types">
214
- <h3>Standard types<a class="headerlink" href="#standard-types" title="Permalink to this heading">#</a></h3>
215
- <p>While the C standard allows for variation in the size of most integer types, Koffi enforces the same definition for most primitive types, listed below:</p>
216
- <div class="table-wrapper colwidths-auto docutils container">
217
- <table class="docutils align-default">
218
- <thead>
219
- <tr class="row-odd"><th class="head"><p>JS type</p></th>
220
- <th class="head"><p>C type</p></th>
221
- <th class="head"><p>Bytes</p></th>
222
- <th class="head"><p>Signedness</p></th>
223
- <th class="head"><p>Note</p></th>
224
- </tr>
225
- </thead>
226
- <tbody>
227
- <tr class="row-even"><td><p>Undefined</p></td>
228
- <td><p>void</p></td>
229
- <td><p>0</p></td>
230
- <td><p></p></td>
231
- <td><p>Only valid as a return type</p></td>
232
- </tr>
233
- <tr class="row-odd"><td><p>Number (integer)</p></td>
234
- <td><p>int8, int8_t</p></td>
235
- <td><p>1</p></td>
236
- <td><p>Signed</p></td>
237
- <td><p></p></td>
238
- </tr>
239
- <tr class="row-even"><td><p>Number (integer)</p></td>
240
- <td><p>uint8, uint8_t</p></td>
241
- <td><p>1</p></td>
242
- <td><p>Unsigned</p></td>
243
- <td><p></p></td>
244
- </tr>
245
- <tr class="row-odd"><td><p>Number (integer)</p></td>
246
- <td><p>char</p></td>
247
- <td><p>1</p></td>
248
- <td><p>Signed</p></td>
249
- <td><p></p></td>
250
- </tr>
251
- <tr class="row-even"><td><p>Number (integer)</p></td>
252
- <td><p>uchar, unsigned char</p></td>
253
- <td><p>1</p></td>
254
- <td><p>Unsigned</p></td>
255
- <td><p></p></td>
256
- </tr>
257
- <tr class="row-odd"><td><p>Number (integer)</p></td>
258
- <td><p>char16, char16_t</p></td>
259
- <td><p>2</p></td>
260
- <td><p>Signed</p></td>
261
- <td><p></p></td>
262
- </tr>
263
- <tr class="row-even"><td><p>Number (integer)</p></td>
264
- <td><p>int16, int16_t</p></td>
265
- <td><p>2</p></td>
266
- <td><p>Signed</p></td>
267
- <td><p></p></td>
268
- </tr>
269
- <tr class="row-odd"><td><p>Number (integer)</p></td>
270
- <td><p>uint16, uint16_t</p></td>
271
- <td><p>2</p></td>
272
- <td><p>Unsigned</p></td>
273
- <td><p></p></td>
274
- </tr>
275
- <tr class="row-even"><td><p>Number (integer)</p></td>
276
- <td><p>short</p></td>
277
- <td><p>2</p></td>
278
- <td><p>Signed</p></td>
279
- <td><p></p></td>
280
- </tr>
281
- <tr class="row-odd"><td><p>Number (integer)</p></td>
282
- <td><p>ushort, unsigned short</p></td>
283
- <td><p>2</p></td>
284
- <td><p>Unsigned</p></td>
285
- <td><p></p></td>
286
- </tr>
287
- <tr class="row-even"><td><p>Number (integer)</p></td>
288
- <td><p>int32, int32_t</p></td>
289
- <td><p>4</p></td>
290
- <td><p>Signed</p></td>
291
- <td><p></p></td>
292
- </tr>
293
- <tr class="row-odd"><td><p>Number (integer)</p></td>
294
- <td><p>uint32, uint32_t</p></td>
295
- <td><p>4</p></td>
296
- <td><p>Unsigned</p></td>
297
- <td><p></p></td>
298
- </tr>
299
- <tr class="row-even"><td><p>Number (integer)</p></td>
300
- <td><p>int</p></td>
301
- <td><p>4</p></td>
302
- <td><p>Signed</p></td>
303
- <td><p></p></td>
304
- </tr>
305
- <tr class="row-odd"><td><p>Number (integer)</p></td>
306
- <td><p>uint, unsigned int</p></td>
307
- <td><p>4</p></td>
308
- <td><p>Unsigned</p></td>
309
- <td><p></p></td>
310
- </tr>
311
- <tr class="row-even"><td><p>Number (integer)</p></td>
312
- <td><p>int64, int64_t</p></td>
313
- <td><p>8</p></td>
314
- <td><p>Signed</p></td>
315
- <td><p></p></td>
316
- </tr>
317
- <tr class="row-odd"><td><p>Number (integer)</p></td>
318
- <td><p>uint64, uint64_t</p></td>
319
- <td><p>8</p></td>
320
- <td><p>Unsigned</p></td>
321
- <td><p></p></td>
322
- </tr>
323
- <tr class="row-even"><td><p>Number (integer)</p></td>
324
- <td><p>longlong, long long</p></td>
325
- <td><p>8</p></td>
326
- <td><p>Signed</p></td>
327
- <td><p></p></td>
328
- </tr>
329
- <tr class="row-odd"><td><p>Number (integer)</p></td>
330
- <td><p>ulonglong, unsigned long long</p></td>
331
- <td><p>8</p></td>
332
- <td><p>Unsigned</p></td>
333
- <td><p></p></td>
334
- </tr>
335
- <tr class="row-even"><td><p>Number (float)</p></td>
336
- <td><p>float32</p></td>
337
- <td><p>4</p></td>
338
- <td><p></p></td>
339
- <td><p></p></td>
340
- </tr>
341
- <tr class="row-odd"><td><p>Number (float)</p></td>
342
- <td><p>float64</p></td>
343
- <td><p>8</p></td>
344
- <td><p></p></td>
345
- <td><p></p></td>
346
- </tr>
347
- <tr class="row-even"><td><p>Number (float)</p></td>
348
- <td><p>float</p></td>
349
- <td><p>4</p></td>
350
- <td><p></p></td>
351
- <td><p></p></td>
352
- </tr>
353
- <tr class="row-odd"><td><p>Number (float)</p></td>
354
- <td><p>double</p></td>
355
- <td><p>8</p></td>
356
- <td><p></p></td>
357
- <td><p></p></td>
358
- </tr>
359
- </tbody>
360
- </table>
361
- </div>
362
- <p>Koffi also accepts BigInt values when converting from JS to C integers. If the value exceeds the range of the C type, Koffi will convert the number to an undefined value. In the reverse direction, BigInt values are automatically used when needed for big 64-bit integers.</p>
363
- <p>Koffi defines a few more types that can change size depending on the OS and the architecture:</p>
364
- <div class="table-wrapper colwidths-auto docutils container">
365
- <table class="docutils align-default">
366
- <thead>
367
- <tr class="row-odd"><th class="head"><p>JS type</p></th>
368
- <th class="head"><p>C type</p></th>
369
- <th class="head"><p>Signedness</p></th>
370
- <th class="head"><p>Note</p></th>
371
- </tr>
372
- </thead>
373
- <tbody>
374
- <tr class="row-even"><td><p>Boolean</p></td>
375
- <td><p>bool</p></td>
376
- <td><p></p></td>
377
- <td><p>Usually one byte</p></td>
378
- </tr>
379
- <tr class="row-odd"><td><p>Number (integer)</p></td>
380
- <td><p>long</p></td>
381
- <td><p>Signed</p></td>
382
- <td><p>4 or 8 bytes depending on platform (LP64, LLP64)</p></td>
383
- </tr>
384
- <tr class="row-even"><td><p>Number (integer)</p></td>
385
- <td><p>ulong</p></td>
386
- <td><p>Unsigned</p></td>
387
- <td><p>4 or 8 bytes depending on platform (LP64, LLP64)</p></td>
388
- </tr>
389
- <tr class="row-odd"><td><p>Number (integer)</p></td>
390
- <td><p>unsigned long</p></td>
391
- <td><p>Unsigned</p></td>
392
- <td><p>4 or 8 bytes depending on platform (LP64, LLP64)</p></td>
393
- </tr>
394
- <tr class="row-even"><td><p>Number (integer)</p></td>
395
- <td><p>intptr</p></td>
396
- <td><p>Signed</p></td>
397
- <td><p>4 or 8 bytes depending on register width</p></td>
398
- </tr>
399
- <tr class="row-odd"><td><p>Number (integer)</p></td>
400
- <td><p>intptr_t</p></td>
401
- <td><p>Signed</p></td>
402
- <td><p>4 or 8 bytes depending on register width</p></td>
403
- </tr>
404
- <tr class="row-even"><td><p>Number (integer)</p></td>
405
- <td><p>uintptr</p></td>
406
- <td><p>Unsigned</p></td>
407
- <td><p>4 or 8 bytes depending on register width</p></td>
408
- </tr>
409
- <tr class="row-odd"><td><p>Number (integer)</p></td>
410
- <td><p>uintptr_t</p></td>
411
- <td><p>Unsigned</p></td>
412
- <td><p>4 or 8 bytes depending on register width</p></td>
413
- </tr>
414
- <tr class="row-even"><td><p>String</p></td>
415
- <td><p>str, string</p></td>
416
- <td><p></p></td>
417
- <td><p>JS strings are converted to and from UTF-8</p></td>
418
- </tr>
419
- <tr class="row-odd"><td><p>String</p></td>
420
- <td><p>str16, string16</p></td>
421
- <td><p></p></td>
422
- <td><p>JS strings are converted to and from UTF-16 (LE)</p></td>
423
- </tr>
424
- </tbody>
425
- </table>
426
- </div>
427
- <p>Primitive types can be specified by name (in a string) or through <code class="docutils literal notranslate"><span class="pre">koffi.types</span></code>:</p>
428
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="c1">// These two lines do the same:</span>
429
- <span class="linenos">2</span><span class="kd">let</span> <span class="nx">struct1</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">({</span> <span class="nx">dummy</span><span class="o">:</span> <span class="s1">&#39;long&#39;</span> <span class="p">});</span>
430
- <span class="linenos">3</span><span class="kd">let</span> <span class="nx">struct2</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">({</span> <span class="nx">dummy</span><span class="o">:</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">types</span><span class="p">.</span><span class="kr">long</span> <span class="p">});</span>
431
- </pre></div>
432
- </div>
433
- </section>
434
- <section id="endian-sensitive-types">
435
- <h3>Endian-sensitive types<a class="headerlink" href="#endian-sensitive-types" title="Permalink to this heading">#</a></h3>
436
- <p>Koffi defines a bunch of endian-sensitive types, which can be used when dealing with binary data (network payloads, binary file formats, etc.).</p>
437
- <div class="table-wrapper colwidths-auto docutils container">
438
- <table class="docutils align-default">
439
- <thead>
440
- <tr class="row-odd"><th class="head"><p>JS type</p></th>
441
- <th class="head"><p>C type</p></th>
442
- <th class="head"><p>Bytes</p></th>
443
- <th class="head"><p>Signedness</p></th>
444
- <th class="head"><p>Endianness</p></th>
445
- </tr>
446
- </thead>
447
- <tbody>
448
- <tr class="row-even"><td><p>Number (integer)</p></td>
449
- <td><p>int16_le, int16_le_t</p></td>
450
- <td><p>2</p></td>
451
- <td><p>Signed</p></td>
452
- <td><p>Little Endian</p></td>
453
- </tr>
454
- <tr class="row-odd"><td><p>Number (integer)</p></td>
455
- <td><p>int16_be, int16_be_t</p></td>
456
- <td><p>2</p></td>
457
- <td><p>Signed</p></td>
458
- <td><p>Big Endian</p></td>
459
- </tr>
460
- <tr class="row-even"><td><p>Number (integer)</p></td>
461
- <td><p>uint16_le, uint16_le_t</p></td>
462
- <td><p>2</p></td>
463
- <td><p>Unsigned</p></td>
464
- <td><p>Little Endian</p></td>
465
- </tr>
466
- <tr class="row-odd"><td><p>Number (integer)</p></td>
467
- <td><p>uint16_be, uint16_be_t</p></td>
468
- <td><p>2</p></td>
469
- <td><p>Unsigned</p></td>
470
- <td><p>Big Endian</p></td>
471
- </tr>
472
- <tr class="row-even"><td><p>Number (integer)</p></td>
473
- <td><p>int32_le, int32_le_t</p></td>
474
- <td><p>4</p></td>
475
- <td><p>Signed</p></td>
476
- <td><p>Little Endian</p></td>
477
- </tr>
478
- <tr class="row-odd"><td><p>Number (integer)</p></td>
479
- <td><p>int32_be, int32_be_t</p></td>
480
- <td><p>4</p></td>
481
- <td><p>Signed</p></td>
482
- <td><p>Big Endian</p></td>
483
- </tr>
484
- <tr class="row-even"><td><p>Number (integer)</p></td>
485
- <td><p>uint32_le, uint32_le_t</p></td>
486
- <td><p>4</p></td>
487
- <td><p>Unsigned</p></td>
488
- <td><p>Little Endian</p></td>
489
- </tr>
490
- <tr class="row-odd"><td><p>Number (integer)</p></td>
491
- <td><p>uint32_be, uint32_be_t</p></td>
492
- <td><p>4</p></td>
493
- <td><p>Unsigned</p></td>
494
- <td><p>Big Endian</p></td>
495
- </tr>
496
- <tr class="row-even"><td><p>Number (integer)</p></td>
497
- <td><p>int64_le, int64_le_t</p></td>
498
- <td><p>8</p></td>
499
- <td><p>Signed</p></td>
500
- <td><p>Little Endian</p></td>
501
- </tr>
502
- <tr class="row-odd"><td><p>Number (integer)</p></td>
503
- <td><p>int64_be, int64_be_t</p></td>
504
- <td><p>8</p></td>
505
- <td><p>Signed</p></td>
506
- <td><p>Big Endian</p></td>
507
- </tr>
508
- <tr class="row-even"><td><p>Number (integer)</p></td>
509
- <td><p>uint64_le, uint64_le_t</p></td>
510
- <td><p>8</p></td>
511
- <td><p>Unsigned</p></td>
512
- <td><p>Little Endian</p></td>
513
- </tr>
514
- <tr class="row-odd"><td><p>Number (integer)</p></td>
515
- <td><p>uint64_be, uint64_be_t</p></td>
516
- <td><p>8</p></td>
517
- <td><p>Unsigned</p></td>
518
- <td><p>Big Endian</p></td>
519
- </tr>
520
- </tbody>
521
- </table>
522
- </div>
523
- </section>
524
- </section>
525
- <section id="struct-types">
526
- <h2>Struct types<a class="headerlink" href="#struct-types" title="Permalink to this heading">#</a></h2>
527
- <section id="struct-definition">
528
- <h3>Struct definition<a class="headerlink" href="#struct-definition" title="Permalink to this heading">#</a></h3>
529
- <p>Koffi converts JS objects to C structs, and vice-versa.</p>
530
- <p>Unlike function declarations, as of now there is only one way to create a struct type, with the <code class="docutils literal notranslate"><span class="pre">koffi.struct()</span></code> function. This function takes two arguments: the first one is the name of the type, and the second one is an object containing the struct member names and types. You can omit the first argument to declare an anonymous struct.</p>
531
- <p>The following example illustrates how to declare the same struct in C and in JS with Koffi:</p>
532
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">A</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
533
- <span class="linenos">2</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">a</span><span class="p">;</span><span class="w"></span>
534
- <span class="linenos">3</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">b</span><span class="p">;</span><span class="w"></span>
535
- <span class="linenos">4</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">c</span><span class="p">;</span><span class="w"></span>
536
- <span class="linenos">5</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
537
- <span class="linenos">6</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">d1</span><span class="p">;</span><span class="w"></span>
538
- <span class="linenos">7</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">d2</span><span class="p">;</span><span class="w"></span>
539
- <span class="linenos">8</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="n">d</span><span class="p">;</span><span class="w"></span>
540
- <span class="linenos">9</span><span class="p">}</span><span class="w"> </span><span class="n">A</span><span class="p">;</span><span class="w"></span>
541
- </pre></div>
542
- </div>
543
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span> <span class="nx">A</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="p">{</span>
544
- <span class="linenos">2</span> <span class="nx">a</span><span class="o">:</span> <span class="s1">&#39;int&#39;</span><span class="p">,</span>
545
- <span class="linenos">3</span> <span class="nx">b</span><span class="o">:</span> <span class="s1">&#39;char&#39;</span><span class="p">,</span>
546
- <span class="linenos">4</span> <span class="nx">c</span><span class="o">:</span> <span class="s1">&#39;const char *&#39;</span><span class="p">,</span> <span class="c1">// Koffi does not care about const, it is ignored</span>
547
- <span class="linenos">5</span> <span class="nx">d</span><span class="o">:</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">({</span>
548
- <span class="linenos">6</span> <span class="nx">d1</span><span class="o">:</span> <span class="s1">&#39;double&#39;</span><span class="p">,</span>
549
- <span class="linenos">7</span> <span class="nx">d2</span><span class="o">:</span> <span class="s1">&#39;double&#39;</span>
550
- <span class="linenos">8</span> <span class="p">})</span>
551
- <span class="linenos">9</span><span class="p">});</span>
552
- </pre></div>
553
- </div>
554
- <p>Koffi follows the C and ABI rules regarding struct alignment and padding.</p>
555
- <p>Once a struct is declared, you can use it by name (with a string, like you can do for primitive types) or through the value returned by the call to <code class="docutils literal notranslate"><span class="pre">koffi.struct()</span></code>. Only the latter is possible when declaring an anonymous struct.</p>
556
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="c1">// The following two function declarations are equivalent, and declare a function taking an A value and returning A</span>
557
- <span class="linenos">2</span><span class="kd">const</span> <span class="nx">Function1</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;A Function(A value)&#39;</span><span class="p">);</span>
558
- <span class="linenos">3</span><span class="kd">const</span> <span class="nx">Function2</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Function&#39;</span><span class="p">,</span> <span class="nx">A</span><span class="p">,</span> <span class="p">[</span><span class="nx">A</span><span class="p">]);</span>
559
- </pre></div>
560
- </div>
561
- <p>Koffi automatically follows the platform C ABI regarding alignment and padding. However, you can override these rules if needed with:</p>
562
- <ul class="simple">
563
- <li><p>Pack all members without padding with <code class="docutils literal notranslate"><span class="pre">koffi.pack()</span></code> (instead of <code class="docutils literal notranslate"><span class="pre">koffi.struct()</span></code>)</p></li>
564
- <li><p>Change alignment of a specific member as shown below</p></li>
565
- </ul>
566
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="c1">// This struct is 3 bytes long</span>
567
- <span class="linenos"> 2</span><span class="kd">const</span> <span class="nx">PackedStruct</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">pack</span><span class="p">(</span><span class="s1">&#39;PackedStruct&#39;</span><span class="p">,</span> <span class="p">{</span>
568
- <span class="linenos"> 3</span> <span class="nx">a</span><span class="o">:</span> <span class="s1">&#39;int8_t&#39;</span><span class="p">,</span>
569
- <span class="linenos"> 4</span> <span class="nx">b</span><span class="o">:</span> <span class="s1">&#39;int16_t&#39;</span>
570
- <span class="linenos"> 5</span><span class="p">});</span>
571
- <span class="linenos"> 6</span>
572
- <span class="linenos"> 7</span><span class="c1">// This one is 18 bytes long, the second member has an alignment requirement of 16 bytes</span>
573
- <span class="linenos"> 8</span><span class="kd">const</span> <span class="nx">BigStruct</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;BigStruct&#39;</span><span class="p">,</span> <span class="p">{</span>
574
- <span class="linenos"> 9</span> <span class="nx">a</span><span class="o">:</span> <span class="s1">&#39;int8_t&#39;</span><span class="p">,</span>
575
- <span class="linenos">10</span> <span class="nx">b</span><span class="o">:</span> <span class="p">[</span><span class="mf">16</span><span class="p">,</span> <span class="s1">&#39;int16_t&#39;</span><span class="p">]</span>
576
- <span class="linenos">11</span><span class="p">})</span>
577
- </pre></div>
578
- </div>
579
- </section>
580
- <section id="opaque-types">
581
- <h3>Opaque types<a class="headerlink" href="#opaque-types" title="Permalink to this heading">#</a></h3>
582
- <p>Many C libraries use some kind of object-oriented API, with a pair of functions dedicated to create and delete objects. An obvious example of this can be found in stdio.h, with the opaque <code class="docutils literal notranslate"><span class="pre">FILE</span> <span class="pre">*</span></code> pointer. You can open and close files with <code class="docutils literal notranslate"><span class="pre">fopen()</span></code> and <code class="docutils literal notranslate"><span class="pre">fclose()</span></code>, and manipule the opaque pointer with other functions such as <code class="docutils literal notranslate"><span class="pre">fread()</span></code> or <code class="docutils literal notranslate"><span class="pre">ftell()</span></code>.</p>
583
- <p>In Koffi, you can manage this with opaque types. Declare the opaque type with <code class="docutils literal notranslate"><span class="pre">koffi.opaque(name)</span></code>, and use a pointer to this type either as a return type or some kind of <a class="reference internal" href="functions#output-parameters"><span class="std std-doc">output parameter</span></a> (with a double pointer).</p>
584
- <div class="admonition note">
585
- <p class="admonition-title">Note</p>
586
- <p>Opaque types <strong>have changed in version 2.0, and again in version 2.1</strong>.</p>
587
- <p>In Koffi 1.x, opaque handles were defined in a way that made them usable directly as parameter and return types, obscuring the underlying pointer.</p>
588
- <p>Now, you must use them through a pointer, and use an array for output parameters. This is shown in the example below (look for the call to <code class="docutils literal notranslate"><span class="pre">ConcatNewOut</span></code> in the JS part), and is described in the section on <a class="reference internal" href="functions#output-parameters"><span class="std std-doc">output parameters</span></a>.</p>
589
- <p>In addition to this, you should use <code class="docutils literal notranslate"><span class="pre">koffi.opaque()</span></code> (introduced in Koffi 2.1) instead of <code class="docutils literal notranslate"><span class="pre">koffi.handle()</span></code> which is deprecated, and will be removed eventually in Koffi 3.0.</p>
590
- <p>Consult the <a class="reference internal" href="changes"><span class="doc std std-doc">migration guide</span></a> for more information.</p>
591
- </div>
592
- <p>The full example below implements an iterative string builder (concatenator) in C, and uses it from Javascript to output a mix of Hello World and FizzBuzz. The builder is hidden behind an opaque type, and is created and destroyed using a pair of C functions: <code class="docutils literal notranslate"><span class="pre">ConcatNew</span></code> (or <code class="docutils literal notranslate"><span class="pre">ConcatNewOut</span></code>) and <code class="docutils literal notranslate"><span class="pre">ConcatFree</span></code>.</p>
593
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="c1">// Build with: clang -fPIC -o handles.so -shared handles.c -Wall -O2</span>
594
- <span class="linenos"> 2</span>
595
- <span class="linenos"> 3</span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdlib.h&gt;</span><span class="cp"></span>
596
- <span class="linenos"> 4</span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdbool.h&gt;</span><span class="cp"></span>
597
- <span class="linenos"> 5</span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdio.h&gt;</span><span class="cp"></span>
598
- <span class="linenos"> 6</span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;errno.h&gt;</span><span class="cp"></span>
599
- <span class="linenos"> 7</span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;string.h&gt;</span><span class="cp"></span>
600
- <span class="linenos"> 8</span>
601
- <span class="linenos"> 9</span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">Fragment</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
602
- <span class="linenos"> 10</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">Fragment</span><span class="w"> </span><span class="o">*</span><span class="n">next</span><span class="p">;</span><span class="w"></span>
603
- <span class="linenos"> 11</span>
604
- <span class="linenos"> 12</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">len</span><span class="p">;</span><span class="w"></span>
605
- <span class="linenos"> 13</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">str</span><span class="p">[];</span><span class="w"></span>
606
- <span class="linenos"> 14</span><span class="p">}</span><span class="w"> </span><span class="n">Fragment</span><span class="p">;</span><span class="w"></span>
607
- <span class="linenos"> 15</span>
608
- <span class="linenos"> 16</span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">Concat</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
609
- <span class="linenos"> 17</span><span class="w"> </span><span class="n">Fragment</span><span class="w"> </span><span class="o">*</span><span class="n">first</span><span class="p">;</span><span class="w"></span>
610
- <span class="linenos"> 18</span><span class="w"> </span><span class="n">Fragment</span><span class="w"> </span><span class="o">*</span><span class="n">last</span><span class="p">;</span><span class="w"></span>
611
- <span class="linenos"> 19</span>
612
- <span class="linenos"> 20</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">total</span><span class="p">;</span><span class="w"></span>
613
- <span class="linenos"> 21</span><span class="p">}</span><span class="w"> </span><span class="n">Concat</span><span class="p">;</span><span class="w"></span>
614
- <span class="linenos"> 22</span>
615
- <span class="linenos"> 23</span><span class="kt">bool</span><span class="w"> </span><span class="nf">ConcatNewOut</span><span class="p">(</span><span class="n">Concat</span><span class="w"> </span><span class="o">**</span><span class="n">out</span><span class="p">)</span><span class="w"></span>
616
- <span class="linenos"> 24</span><span class="p">{</span><span class="w"></span>
617
- <span class="linenos"> 25</span><span class="w"> </span><span class="n">Concat</span><span class="w"> </span><span class="o">*</span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="o">*</span><span class="n">c</span><span class="p">));</span><span class="w"></span>
618
- <span class="linenos"> 26</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">c</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
619
- <span class="linenos"> 27</span><span class="w"> </span><span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;Failed to allocate memory: %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">strerror</span><span class="p">(</span><span class="n">errno</span><span class="p">));</span><span class="w"></span>
620
- <span class="linenos"> 28</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">false</span><span class="p">;</span><span class="w"></span>
621
- <span class="linenos"> 29</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
622
- <span class="linenos"> 30</span>
623
- <span class="linenos"> 31</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">first</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span><span class="w"></span>
624
- <span class="linenos"> 32</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">last</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span><span class="w"></span>
625
- <span class="linenos"> 33</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">total</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
626
- <span class="linenos"> 34</span>
627
- <span class="linenos"> 35</span><span class="w"> </span><span class="o">*</span><span class="n">out</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">c</span><span class="p">;</span><span class="w"></span>
628
- <span class="linenos"> 36</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">true</span><span class="p">;</span><span class="w"></span>
629
- <span class="linenos"> 37</span><span class="p">}</span><span class="w"></span>
630
- <span class="linenos"> 38</span>
631
- <span class="linenos"> 39</span><span class="n">Concat</span><span class="w"> </span><span class="o">*</span><span class="nf">ConcatNew</span><span class="p">()</span><span class="w"></span>
632
- <span class="linenos"> 40</span><span class="p">{</span><span class="w"></span>
633
- <span class="linenos"> 41</span><span class="w"> </span><span class="n">Concat</span><span class="w"> </span><span class="o">*</span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span><span class="w"></span>
634
- <span class="linenos"> 42</span><span class="w"> </span><span class="n">ConcatNewOut</span><span class="p">(</span><span class="o">&amp;</span><span class="n">c</span><span class="p">);</span><span class="w"></span>
635
- <span class="linenos"> 43</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">c</span><span class="p">;</span><span class="w"></span>
636
- <span class="linenos"> 44</span><span class="p">}</span><span class="w"></span>
637
- <span class="linenos"> 45</span>
638
- <span class="linenos"> 46</span><span class="kt">void</span><span class="w"> </span><span class="nf">ConcatFree</span><span class="p">(</span><span class="n">Concat</span><span class="w"> </span><span class="o">*</span><span class="n">c</span><span class="p">)</span><span class="w"></span>
639
- <span class="linenos"> 47</span><span class="p">{</span><span class="w"></span>
640
- <span class="linenos"> 48</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">c</span><span class="p">)</span><span class="w"></span>
641
- <span class="linenos"> 49</span><span class="w"> </span><span class="k">return</span><span class="p">;</span><span class="w"></span>
642
- <span class="linenos"> 50</span>
643
- <span class="linenos"> 51</span><span class="w"> </span><span class="n">Fragment</span><span class="w"> </span><span class="o">*</span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">first</span><span class="p">;</span><span class="w"></span>
644
- <span class="linenos"> 52</span>
645
- <span class="linenos"> 53</span><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">f</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
646
- <span class="linenos"> 54</span><span class="w"> </span><span class="n">Fragment</span><span class="w"> </span><span class="o">*</span><span class="n">next</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span><span class="w"></span>
647
- <span class="linenos"> 55</span><span class="w"> </span><span class="n">free</span><span class="p">(</span><span class="n">f</span><span class="p">);</span><span class="w"></span>
648
- <span class="linenos"> 56</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">next</span><span class="p">;</span><span class="w"></span>
649
- <span class="linenos"> 57</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
650
- <span class="linenos"> 58</span>
651
- <span class="linenos"> 59</span><span class="w"> </span><span class="n">free</span><span class="p">(</span><span class="n">c</span><span class="p">);</span><span class="w"></span>
652
- <span class="linenos"> 60</span><span class="p">}</span><span class="w"></span>
653
- <span class="linenos"> 61</span>
654
- <span class="linenos"> 62</span><span class="kt">bool</span><span class="w"> </span><span class="nf">ConcatAppend</span><span class="p">(</span><span class="n">Concat</span><span class="w"> </span><span class="o">*</span><span class="n">c</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">frag</span><span class="p">)</span><span class="w"></span>
655
- <span class="linenos"> 63</span><span class="p">{</span><span class="w"></span>
656
- <span class="linenos"> 64</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">strlen</span><span class="p">(</span><span class="n">frag</span><span class="p">);</span><span class="w"></span>
657
- <span class="linenos"> 65</span>
658
- <span class="linenos"> 66</span><span class="w"> </span><span class="n">Fragment</span><span class="w"> </span><span class="o">*</span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span><span class="w"></span>
659
- <span class="linenos"> 67</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">f</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
660
- <span class="linenos"> 68</span><span class="w"> </span><span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;Failed to allocate memory: %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">strerror</span><span class="p">(</span><span class="n">errno</span><span class="p">));</span><span class="w"></span>
661
- <span class="linenos"> 69</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">false</span><span class="p">;</span><span class="w"></span>
662
- <span class="linenos"> 70</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
663
- <span class="linenos"> 71</span>
664
- <span class="linenos"> 72</span><span class="w"> </span><span class="n">f</span><span class="o">-&gt;</span><span class="n">next</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span><span class="w"></span>
665
- <span class="linenos"> 73</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">c</span><span class="o">-&gt;</span><span class="n">last</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
666
- <span class="linenos"> 74</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">last</span><span class="o">-&gt;</span><span class="n">next</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f</span><span class="p">;</span><span class="w"></span>
667
- <span class="linenos"> 75</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
668
- <span class="linenos"> 76</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">first</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f</span><span class="p">;</span><span class="w"></span>
669
- <span class="linenos"> 77</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
670
- <span class="linenos"> 78</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">last</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f</span><span class="p">;</span><span class="w"></span>
671
- <span class="linenos"> 79</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">total</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">len</span><span class="p">;</span><span class="w"></span>
672
- <span class="linenos"> 80</span>
673
- <span class="linenos"> 81</span><span class="w"> </span><span class="n">f</span><span class="o">-&gt;</span><span class="n">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">len</span><span class="p">;</span><span class="w"></span>
674
- <span class="linenos"> 82</span><span class="w"> </span><span class="n">memcpy</span><span class="p">(</span><span class="n">f</span><span class="o">-&gt;</span><span class="n">str</span><span class="p">,</span><span class="w"> </span><span class="n">frag</span><span class="p">,</span><span class="w"> </span><span class="n">len</span><span class="p">);</span><span class="w"></span>
675
- <span class="linenos"> 83</span><span class="w"> </span><span class="n">f</span><span class="o">-&gt;</span><span class="n">str</span><span class="p">[</span><span class="n">len</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
676
- <span class="linenos"> 84</span>
677
- <span class="linenos"> 85</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">true</span><span class="p">;</span><span class="w"></span>
678
- <span class="linenos"> 86</span><span class="p">}</span><span class="w"></span>
679
- <span class="linenos"> 87</span>
680
- <span class="linenos"> 88</span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="nf">ConcatBuild</span><span class="p">(</span><span class="n">Concat</span><span class="w"> </span><span class="o">*</span><span class="n">c</span><span class="p">)</span><span class="w"></span>
681
- <span class="linenos"> 89</span><span class="p">{</span><span class="w"></span>
682
- <span class="linenos"> 90</span><span class="w"> </span><span class="n">Fragment</span><span class="w"> </span><span class="o">*</span><span class="n">r</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="o">*</span><span class="n">r</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">total</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span><span class="w"></span>
683
- <span class="linenos"> 91</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">r</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
684
- <span class="linenos"> 92</span><span class="w"> </span><span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;Failed to allocate memory: %s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">strerror</span><span class="p">(</span><span class="n">errno</span><span class="p">));</span><span class="w"></span>
685
- <span class="linenos"> 93</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span><span class="w"></span>
686
- <span class="linenos"> 94</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
687
- <span class="linenos"> 95</span>
688
- <span class="linenos"> 96</span><span class="w"> </span><span class="n">r</span><span class="o">-&gt;</span><span class="n">next</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span><span class="w"></span>
689
- <span class="linenos"> 97</span><span class="w"> </span><span class="n">r</span><span class="o">-&gt;</span><span class="n">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
690
- <span class="linenos"> 98</span>
691
- <span class="linenos"> 99</span><span class="w"> </span><span class="n">Fragment</span><span class="w"> </span><span class="o">*</span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">first</span><span class="p">;</span><span class="w"></span>
692
- <span class="linenos">100</span>
693
- <span class="linenos">101</span><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">f</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
694
- <span class="linenos">102</span><span class="w"> </span><span class="n">Fragment</span><span class="w"> </span><span class="o">*</span><span class="n">next</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span><span class="w"></span>
695
- <span class="linenos">103</span>
696
- <span class="linenos">104</span><span class="w"> </span><span class="n">memcpy</span><span class="p">(</span><span class="n">r</span><span class="o">-&gt;</span><span class="n">str</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">r</span><span class="o">-&gt;</span><span class="n">len</span><span class="p">,</span><span class="w"> </span><span class="n">f</span><span class="o">-&gt;</span><span class="n">str</span><span class="p">,</span><span class="w"> </span><span class="n">f</span><span class="o">-&gt;</span><span class="n">len</span><span class="p">);</span><span class="w"></span>
697
- <span class="linenos">105</span><span class="w"> </span><span class="n">r</span><span class="o">-&gt;</span><span class="n">len</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">f</span><span class="o">-&gt;</span><span class="n">len</span><span class="p">;</span><span class="w"></span>
698
- <span class="linenos">106</span>
699
- <span class="linenos">107</span><span class="w"> </span><span class="n">free</span><span class="p">(</span><span class="n">f</span><span class="p">);</span><span class="w"></span>
700
- <span class="linenos">108</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">next</span><span class="p">;</span><span class="w"></span>
701
- <span class="linenos">109</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
702
- <span class="linenos">110</span><span class="w"> </span><span class="n">r</span><span class="o">-&gt;</span><span class="n">str</span><span class="p">[</span><span class="n">r</span><span class="o">-&gt;</span><span class="n">len</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
703
- <span class="linenos">111</span>
704
- <span class="linenos">112</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">first</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">r</span><span class="p">;</span><span class="w"></span>
705
- <span class="linenos">113</span><span class="w"> </span><span class="n">c</span><span class="o">-&gt;</span><span class="n">last</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">r</span><span class="p">;</span><span class="w"></span>
706
- <span class="linenos">114</span>
707
- <span class="linenos">115</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">r</span><span class="o">-&gt;</span><span class="n">str</span><span class="p">;</span><span class="w"></span>
708
- <span class="linenos">116</span><span class="p">}</span><span class="w"></span>
709
- </pre></div>
710
- </div>
711
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span> <span class="nx">koffi</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span>
712
- <span class="linenos"> 2</span><span class="kd">const</span> <span class="nx">lib</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;./handles.so&#39;</span><span class="p">);</span>
713
- <span class="linenos"> 3</span>
714
- <span class="linenos"> 4</span><span class="kd">const</span> <span class="nx">Concat</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">opaque</span><span class="p">(</span><span class="s1">&#39;Concat&#39;</span><span class="p">);</span>
715
- <span class="linenos"> 5</span><span class="kd">const</span> <span class="nx">ConcatNewOut</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool ConcatNewOut(_Out_ Concat **out)&#39;</span><span class="p">);</span>
716
- <span class="linenos"> 6</span><span class="kd">const</span> <span class="nx">ConcatNew</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Concat *ConcatNew()&#39;</span><span class="p">);</span>
717
- <span class="linenos"> 7</span><span class="kd">const</span> <span class="nx">ConcatFree</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;void ConcatFree(Concat *c)&#39;</span><span class="p">);</span>
718
- <span class="linenos"> 8</span><span class="kd">const</span> <span class="nx">ConcatAppend</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool ConcatAppend(Concat *c, const char *frag)&#39;</span><span class="p">);</span>
719
- <span class="linenos"> 9</span><span class="kd">const</span> <span class="nx">ConcatBuild</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;const char *ConcatBuild(Concat *c)&#39;</span><span class="p">);</span>
720
- <span class="linenos">10</span>
721
- <span class="linenos">11</span><span class="kd">let</span> <span class="nx">c</span> <span class="o">=</span> <span class="nx">ConcatNew</span><span class="p">();</span>
722
- <span class="linenos">12</span><span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">c</span><span class="p">)</span> <span class="p">{</span>
723
- <span class="linenos">13</span> <span class="c1">// This is stupid, it does the same, but try both versions (return value, output parameter)</span>
724
- <span class="linenos">14</span> <span class="kd">let</span> <span class="nx">ptr</span> <span class="o">=</span> <span class="p">[</span><span class="kc">null</span><span class="p">];</span>
725
- <span class="linenos">15</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ConcatNewOut</span><span class="p">(</span><span class="nx">ptr</span><span class="p">))</span>
726
- <span class="linenos">16</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
727
- <span class="linenos">17</span> <span class="nx">c</span> <span class="o">=</span> <span class="nx">ptr</span><span class="p">[</span><span class="mf">0</span><span class="p">];</span>
728
- <span class="linenos">18</span><span class="p">}</span>
729
- <span class="linenos">19</span>
730
- <span class="linenos">20</span><span class="k">try</span> <span class="p">{</span>
731
- <span class="linenos">21</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span> <span class="s1">&#39;Hello... &#39;</span><span class="p">))</span>
732
- <span class="linenos">22</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
733
- <span class="linenos">23</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span> <span class="s1">&#39;World!\n&#39;</span><span class="p">))</span>
734
- <span class="linenos">24</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
735
- <span class="linenos">25</span>
736
- <span class="linenos">26</span> <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mf">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="mf">30</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
737
- <span class="linenos">27</span> <span class="kd">let</span> <span class="nx">frag</span><span class="p">;</span>
738
- <span class="linenos">28</span> <span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mf">15</span> <span class="o">==</span> <span class="mf">0</span><span class="p">)</span> <span class="p">{</span>
739
- <span class="linenos">29</span> <span class="nx">frag</span> <span class="o">=</span> <span class="s1">&#39;FizzBuzz&#39;</span><span class="p">;</span>
740
- <span class="linenos">30</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mf">5</span> <span class="o">==</span> <span class="mf">0</span><span class="p">)</span> <span class="p">{</span>
741
- <span class="linenos">31</span> <span class="nx">frag</span> <span class="o">=</span> <span class="s1">&#39;Buzz&#39;</span><span class="p">;</span>
742
- <span class="linenos">32</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">%</span> <span class="mf">3</span> <span class="o">==</span> <span class="mf">0</span><span class="p">)</span> <span class="p">{</span>
743
- <span class="linenos">33</span> <span class="nx">frag</span> <span class="o">=</span> <span class="s1">&#39;Fizz&#39;</span><span class="p">;</span>
744
- <span class="linenos">34</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
745
- <span class="linenos">35</span> <span class="nx">frag</span> <span class="o">=</span> <span class="nb">String</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
746
- <span class="linenos">36</span> <span class="p">}</span>
747
- <span class="linenos">37</span>
748
- <span class="linenos">38</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span> <span class="nx">frag</span><span class="p">))</span>
749
- <span class="linenos">39</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
750
- <span class="linenos">40</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">ConcatAppend</span><span class="p">(</span><span class="nx">c</span><span class="p">,</span> <span class="s1">&#39; &#39;</span><span class="p">))</span>
751
- <span class="linenos">41</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
752
- <span class="linenos">42</span> <span class="p">}</span>
753
- <span class="linenos">43</span>
754
- <span class="linenos">44</span> <span class="kd">let</span> <span class="nx">str</span> <span class="o">=</span> <span class="nx">ConcatBuild</span><span class="p">(</span><span class="nx">c</span><span class="p">);</span>
755
- <span class="linenos">45</span> <span class="k">if</span> <span class="p">(</span><span class="nx">str</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span>
756
- <span class="linenos">46</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Allocation failure&#39;</span><span class="p">);</span>
757
- <span class="linenos">47</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">str</span><span class="p">);</span>
758
- <span class="linenos">48</span><span class="p">}</span> <span class="k">finally</span> <span class="p">{</span>
759
- <span class="linenos">49</span> <span class="nx">ConcatFree</span><span class="p">(</span><span class="nx">c</span><span class="p">);</span>
760
- <span class="linenos">50</span><span class="p">}</span>
761
- </pre></div>
762
- </div>
763
- </section>
764
- </section>
765
- <section id="pointer-types">
766
- <h2>Pointer types<a class="headerlink" href="#pointer-types" title="Permalink to this heading">#</a></h2>
767
- <p>In C, pointer arguments are used for differenty purposes. It is important to distinguish these use cases because Koffi provides different ways to deal with each of them:</p>
768
- <ul class="simple">
769
- <li><p><strong>Struct pointers</strong>: Use of struct pointers by C libraries fall in two cases: avoid (potentially) expensive copies, and to let the function change struct contents (output or input/output arguments).</p></li>
770
- <li><p><strong>Opaque pointers</strong>: the library does not expose the contents of the structs, and only provides you with a pointer to it (e.g. <code class="docutils literal notranslate"><span class="pre">FILE</span> <span class="pre">*</span></code>). Only the functions provided by the library can do something with this pointer, in Koffi we call this an opaque type. This is usually done for ABI-stability reason, and to prevent library users from messing directly with library internals.</p></li>
771
- <li><p><strong>Pointers to primitive types</strong>: This is more rare, and generally used for output or input/output arguments. The Win32 API has a lot of these.</p></li>
772
- <li><p><strong>Arrays</strong>: in C, you dynamically-sized arrays are usually passed to functions with pointers, either NULL-terminated (or any other sentinel value) or with an additional length argument.</p></li>
773
- </ul>
774
- <section id="struct-pointers">
775
- <h3>Struct pointers<a class="headerlink" href="#struct-pointers" title="Permalink to this heading">#</a></h3>
776
- <p>The following Win32 example uses <code class="docutils literal notranslate"><span class="pre">GetCursorPos()</span></code> (with an output parameter) to retrieve and show the current cursor position.</p>
777
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span> <span class="nx">koffi</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span>
778
- <span class="linenos"> 2</span><span class="kd">const</span> <span class="nx">lib</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;kernel32.dll&#39;</span><span class="p">);</span>
779
- <span class="linenos"> 3</span>
780
- <span class="linenos"> 4</span><span class="c1">// Type declarations</span>
781
- <span class="linenos"> 5</span><span class="kd">const</span> <span class="nx">POINT</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;POINT&#39;</span><span class="p">,</span> <span class="p">{</span>
782
- <span class="linenos"> 6</span> <span class="nx">x</span><span class="o">:</span> <span class="s1">&#39;long&#39;</span><span class="p">,</span>
783
- <span class="linenos"> 7</span> <span class="nx">y</span><span class="o">:</span> <span class="s1">&#39;long&#39;</span>
784
- <span class="linenos"> 8</span><span class="p">});</span>
785
- <span class="linenos"> 9</span>
786
- <span class="linenos">10</span><span class="c1">// Functions declarations</span>
787
- <span class="linenos">11</span><span class="kd">const</span> <span class="nx">GetCursorPos</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;int __stdcall GetCursorPos(_Out_ POINT *pos)&#39;</span><span class="p">);</span>
788
- <span class="linenos">12</span>
789
- <span class="linenos">13</span><span class="c1">// Get and show cursor position</span>
790
- <span class="linenos">14</span><span class="kd">let</span> <span class="nx">pos</span> <span class="o">=</span> <span class="p">{};</span>
791
- <span class="linenos">15</span><span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">GetCursorPos</span><span class="p">(</span><span class="nx">pos</span><span class="p">))</span>
792
- <span class="linenos">16</span> <span class="k">throw</span> <span class="ow">new</span> <span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;Failed to get cursor position&#39;</span><span class="p">);</span>
793
- <span class="linenos">17</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">pos</span><span class="p">);</span>
794
- </pre></div>
795
- </div>
796
- </section>
797
- <section id="named-pointer-types">
798
- <h3>Named pointer types<a class="headerlink" href="#named-pointer-types" title="Permalink to this heading">#</a></h3>
799
- <p><em>New in Koffi 2.0</em></p>
800
- <p>Some C libraries use handles, which behave as pointers to opaque structs. An example of this is the HANDLE type in the Win32 API. If you want to reproduce this behavior, you can define a <strong>named pointer type</strong> to an opaque type, like so:</p>
801
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span> <span class="nx">HANDLE</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">pointer</span><span class="p">(</span><span class="s1">&#39;HANDLE&#39;</span><span class="p">,</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">opaque</span><span class="p">());</span>
802
- <span class="linenos">2</span>
803
- <span class="linenos">3</span><span class="c1">// And now you get to use it this way:</span>
804
- <span class="linenos">4</span><span class="kd">const</span> <span class="nx">GetHandleInformation</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool __stdcall GetHandleInformation(HANDLE h, _Out_ uint32_t *flags)&#39;</span><span class="p">);</span>
805
- <span class="linenos">5</span><span class="kd">const</span> <span class="nx">CloseHandle</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;bool __stdcall CloseHandle(HANDLE h)&#39;</span><span class="p">);</span>
806
- </pre></div>
807
- </div>
808
- </section>
809
- <section id="pointers-to-primitive-types">
810
- <h3>Pointers to primitive types<a class="headerlink" href="#pointers-to-primitive-types" title="Permalink to this heading">#</a></h3>
811
- <p>In javascript, it is not possible to pass a primitive value by reference to another function. This means that you cannot call a function and expect it to modify the value of one of its number or string parameter.</p>
812
- <p>However, arrays and objects (among others) are reference type values. Assigning an array or an object from one variable to another does not invole any copy. Instead, as the following example illustrates, the new variable references the same array as the first:</p>
813
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">let</span> <span class="nx">list1</span> <span class="o">=</span> <span class="p">[</span><span class="mf">1</span><span class="p">,</span> <span class="mf">2</span><span class="p">];</span>
814
- <span class="linenos">2</span><span class="kd">let</span> <span class="nx">list2</span> <span class="o">=</span> <span class="nx">list1</span><span class="p">;</span>
815
- <span class="linenos">3</span>
816
- <span class="linenos">4</span><span class="nx">list2</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span> <span class="o">=</span> <span class="mf">42</span><span class="p">;</span>
817
- <span class="linenos">5</span>
818
- <span class="linenos">6</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">list1</span><span class="p">);</span> <span class="c1">// Prints [1, 42]</span>
819
- </pre></div>
820
- </div>
821
- <p>All of this means that C functions that are expected to modify their primitive output values (such as an <code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">*</span></code> parameter) cannot be used directly. However, thanks to Koffi’s transparent array support, you can use Javascript arrays to approximate reference semantics with single-element arrays.</p>
822
- <p>Below, you can find an example of an addition function where the result is stored in an <code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">*</span></code> input/output parameter and how to use this function from Koffi.</p>
823
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kt">void</span><span class="w"> </span><span class="nf">AddInt</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">dest</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">add</span><span class="p">)</span><span class="w"></span>
824
- <span class="linenos">2</span><span class="p">{</span><span class="w"></span>
825
- <span class="linenos">3</span><span class="w"> </span><span class="o">*</span><span class="n">dest</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">add</span><span class="p">;</span><span class="w"></span>
826
- <span class="linenos">4</span><span class="p">}</span><span class="w"></span>
827
- </pre></div>
828
- </div>
829
- <p>You can simply pass a single-element array as the first argument:</p>
830
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span> <span class="nx">AddInt</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;void AddInt(_Inout_ int *dest, int add)&#39;</span><span class="p">);</span>
831
- <span class="linenos">2</span>
832
- <span class="linenos">3</span><span class="kd">let</span> <span class="nx">sum</span> <span class="o">=</span> <span class="p">[</span><span class="mf">36</span><span class="p">];</span>
833
- <span class="linenos">4</span><span class="nx">AddInt</span><span class="p">(</span><span class="nx">sum</span><span class="p">,</span> <span class="mf">6</span><span class="p">);</span>
834
- <span class="linenos">5</span>
835
- <span class="linenos">6</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">sum</span><span class="p">[</span><span class="mf">0</span><span class="p">]);</span> <span class="c1">// Prints 42</span>
836
- </pre></div>
837
- </div>
838
- </section>
839
- </section>
840
- <section id="array-types">
841
- <h2>Array types<a class="headerlink" href="#array-types" title="Permalink to this heading">#</a></h2>
842
- <section id="fixed-size-c-arrays">
843
- <h3>Fixed-size C arrays<a class="headerlink" href="#fixed-size-c-arrays" title="Permalink to this heading">#</a></h3>
844
- <p>Fixed-size arrays are declared with <code class="docutils literal notranslate"><span class="pre">koffi.array(type,</span> <span class="pre">length)</span></code>. Just like in C, they cannot be passed as functions parameters (they degenerate to pointers), or returned by value. You can however embed them in struct types.</p>
845
- <p>Koffi applies the following conversion rules when passing arrays to/from C:</p>
846
- <ul class="simple">
847
- <li><p><strong>JS to C</strong>: Koffi can take a normal Array (e.g. <code class="docutils literal notranslate"><span class="pre">[1,</span> <span class="pre">2]</span></code>) or a TypedArray of the correct type (e.g. <code class="docutils literal notranslate"><span class="pre">Uint8Array</span></code> for an array of <code class="docutils literal notranslate"><span class="pre">uint8_t</span></code> numbers)</p></li>
848
- <li><p><strong>C to JS</strong> (return value, output parameters, callbacks): Koffi will use a TypedArray if possible. But you can change this behavior when you create the array type with the optional hint argument: <code class="docutils literal notranslate"><span class="pre">koffi.array('uint8_t',</span> <span class="pre">64,</span> <span class="pre">'array')</span></code>. For non-number types, such as arrays of strings or structs, Koffi creates normal arrays.</p></li>
849
- </ul>
850
- <p>See the example below:</p>
851
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="kd">const</span> <span class="nx">koffi</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span>
852
- <span class="linenos"> 2</span>
853
- <span class="linenos"> 3</span><span class="c1">// Those two structs are exactly the same, only the array conversion hint is different</span>
854
- <span class="linenos"> 4</span><span class="kd">const</span> <span class="nx">Foo1</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;Foo&#39;</span><span class="p">,</span> <span class="p">{</span>
855
- <span class="linenos"> 5</span> <span class="nx">i</span><span class="o">:</span> <span class="s1">&#39;int&#39;</span><span class="p">,</span>
856
- <span class="linenos"> 6</span> <span class="nx">a16</span><span class="o">:</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">array</span><span class="p">(</span><span class="s1">&#39;int16_t&#39;</span><span class="p">,</span> <span class="mf">8</span><span class="p">)</span>
857
- <span class="linenos"> 7</span><span class="p">});</span>
858
- <span class="linenos"> 8</span><span class="kd">const</span> <span class="nx">Foo2</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">struct</span><span class="p">(</span><span class="s1">&#39;Foo&#39;</span><span class="p">,</span> <span class="p">{</span>
859
- <span class="linenos"> 9</span> <span class="nx">i</span><span class="o">:</span> <span class="s1">&#39;int&#39;</span><span class="p">,</span>
860
- <span class="linenos">10</span> <span class="nx">a16</span><span class="o">:</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">array</span><span class="p">(</span><span class="s1">&#39;int16_t&#39;</span><span class="p">,</span> <span class="mf">8</span><span class="p">,</span> <span class="s1">&#39;array&#39;</span><span class="p">)</span>
861
- <span class="linenos">11</span><span class="p">});</span>
862
- <span class="linenos">12</span>
863
- <span class="linenos">13</span><span class="c1">// Uses an hypothetical C function that just returns the struct passed as a parameter</span>
864
- <span class="linenos">14</span><span class="kd">const</span> <span class="nx">ReturnFoo1</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Foo1 ReturnFoo(Foo1 p)&#39;</span><span class="p">);</span>
865
- <span class="linenos">15</span><span class="kd">const</span> <span class="nx">ReturnFoo2</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;Foo2 ReturnFoo(Foo2 p)&#39;</span><span class="p">);</span>
866
- <span class="linenos">16</span>
867
- <span class="linenos">17</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">ReturnFoo1</span><span class="p">({</span> <span class="nx">i</span><span class="o">:</span> <span class="mf">5</span><span class="p">,</span> <span class="nx">a16</span><span class="o">:</span> <span class="p">[</span><span class="mf">6</span><span class="p">,</span> <span class="mf">8</span><span class="p">]</span> <span class="p">}))</span> <span class="c1">// Prints { i: 5, a16: Int16Array(2) [6, 8] }</span>
868
- <span class="linenos">18</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">ReturnFoo2</span><span class="p">({</span> <span class="nx">i</span><span class="o">:</span> <span class="mf">5</span><span class="p">,</span> <span class="nx">a16</span><span class="o">:</span> <span class="p">[</span><span class="mf">6</span><span class="p">,</span> <span class="mf">8</span><span class="p">]</span> <span class="p">}))</span> <span class="c1">// Prints { i: 5, a16: [6, 8] }</span>
869
- </pre></div>
870
- </div>
871
- </section>
872
- <section id="fixed-size-string-buffers">
873
- <h3>Fixed-size string buffers<a class="headerlink" href="#fixed-size-string-buffers" title="Permalink to this heading">#</a></h3>
874
- <p>Koffi can also convert JS strings to fixed-sized arrays in the following cases:</p>
875
- <ul class="simple">
876
- <li><p><strong>char arrays</strong> are filled with the UTF-8 encoded string, truncated if needed. The buffer is always NUL-terminated.</p></li>
877
- <li><p><strong>char16 (or char16_t) arrays</strong> are filled with the UTF-16 encoded string, truncated if needed. The buffer is always NUL-terminated.</p></li>
878
- </ul>
879
- <p>The reverse case is also true, Koffi can convert a C fixed-size buffer to a JS string. This happens by default for char, char16 and char16_t arrays, but you can also explicitly ask for this with the <code class="docutils literal notranslate"><span class="pre">string</span></code> array hint (e.g. <code class="docutils literal notranslate"><span class="pre">koffi.array('char',</span> <span class="pre">8,</span> <span class="pre">'string')</span></code>).</p>
880
- </section>
881
- <section id="array-pointers-dynamic-arrays">
882
- <h3>Array pointers (dynamic arrays)<a class="headerlink" href="#array-pointers-dynamic-arrays" title="Permalink to this heading">#</a></h3>
883
- <p>In C, dynamically-sized arrays are usually passed around as pointers. The length is either passed as an additional argument, or inferred from the array content itself, for example with a terminating sentinel value (such as a NULL pointers in the case of an array of strings).</p>
884
- <p>Koffi can translate JS arrays and TypedArrays to pointer arguments. However, because C does not have a proper notion of dynamically-sized arrays (fat pointers), you need to provide the length or the sentinel value yourself depending on the API.</p>
885
- <p>Here is a simple example of a C function taking a NULL-terminated list of strings as input, to calculate the total length of all strings.</p>
886
- <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="linenos"> 1</span><span class="c1">// Build with: clang -fPIC -o length.so -shared length.c -Wall -O2</span>
887
- <span class="linenos"> 2</span>
888
- <span class="linenos"> 3</span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdlib.h&gt;</span><span class="cp"></span>
889
- <span class="linenos"> 4</span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdint.h&gt;</span><span class="cp"></span>
890
- <span class="linenos"> 5</span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;string.h&gt;</span><span class="cp"></span>
891
- <span class="linenos"> 6</span>
892
- <span class="linenos"> 7</span><span class="kt">int64_t</span><span class="w"> </span><span class="nf">ComputeTotalLength</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">**</span><span class="n">strings</span><span class="p">)</span><span class="w"></span>
893
- <span class="linenos"> 8</span><span class="p">{</span><span class="w"></span>
894
- <span class="linenos"> 9</span><span class="w"> </span><span class="kt">int64_t</span><span class="w"> </span><span class="n">total</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
895
- <span class="linenos">10</span>
896
- <span class="linenos">11</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">**</span><span class="n">ptr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">strings</span><span class="p">;</span><span class="w"> </span><span class="o">*</span><span class="n">ptr</span><span class="p">;</span><span class="w"> </span><span class="n">ptr</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
897
- <span class="linenos">12</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">str</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="n">ptr</span><span class="p">;</span><span class="w"></span>
898
- <span class="linenos">13</span><span class="w"> </span><span class="n">total</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">strlen</span><span class="p">(</span><span class="n">str</span><span class="p">);</span><span class="w"></span>
899
- <span class="linenos">14</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
900
- <span class="linenos">15</span>
901
- <span class="linenos">16</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">total</span><span class="p">;</span><span class="w"></span>
902
- <span class="linenos">17</span><span class="p">}</span><span class="w"></span>
903
- </pre></div>
904
- </div>
905
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span> <span class="nx">koffi</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koffi&#39;</span><span class="p">);</span>
906
- <span class="linenos">2</span><span class="kd">const</span> <span class="nx">lib</span> <span class="o">=</span> <span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;./length.so&#39;</span><span class="p">);</span>
907
- <span class="linenos">3</span>
908
- <span class="linenos">4</span><span class="kd">const</span> <span class="nx">ComputeTotalLength</span> <span class="o">=</span> <span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">&#39;int64_t ComputeTotalLength(const char **strings)&#39;</span><span class="p">);</span>
909
- <span class="linenos">5</span>
910
- <span class="linenos">6</span><span class="kd">let</span> <span class="nx">strings</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;Get&#39;</span><span class="p">,</span> <span class="s1">&#39;Total&#39;</span><span class="p">,</span> <span class="s1">&#39;Length&#39;</span><span class="p">,</span> <span class="kc">null</span><span class="p">];</span>
911
- <span class="linenos">7</span><span class="kd">let</span> <span class="nx">total</span> <span class="o">=</span> <span class="nx">ComputeTotalLength</span><span class="p">(</span><span class="nx">strings</span><span class="p">);</span>
912
- <span class="linenos">8</span>
913
- <span class="linenos">9</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">total</span><span class="p">);</span> <span class="c1">// Prints 14</span>
914
- </pre></div>
915
- </div>
916
- <p>By default, just like for objects, array arguments are copied from JS to C but not vice-versa. You can however change the direction as documented in the section on <a class="reference internal" href="functions#output-parameters"><span class="std std-doc">output parameters</span></a>.</p>
917
- </section>
918
- </section>
919
- <section id="disposable-types">
920
- <h2>Disposable types<a class="headerlink" href="#disposable-types" title="Permalink to this heading">#</a></h2>
921
- <p>Disposable types allow you to register a function that will automatically called after each C to JS conversion performed by Koffi. This can be used to avoid leaking heap-allocated strings, for example.</p>
922
- <p>Read the documentation for <a class="reference internal" href="functions#heap-allocated-values"><span class="std std-doc">disposable types</span></a> on the page about function calls.</p>
923
- </section>
924
- <section id="utility-functions">
925
- <h2>Utility functions<a class="headerlink" href="#utility-functions" title="Permalink to this heading">#</a></h2>
926
- <section id="type-introspection">
927
- <h3>Type introspection<a class="headerlink" href="#type-introspection" title="Permalink to this heading">#</a></h3>
928
- <p><em>New in Koffi 2.0: <code class="docutils literal notranslate"><span class="pre">koffi.resolve()</span></code></em></p>
929
- <p>Koffi exposes three functions to explore type information:</p>
930
- <ul class="simple">
931
- <li><p><code class="docutils literal notranslate"><span class="pre">koffi.sizeof(type)</span></code> to get the size of a type</p></li>
932
- <li><p><code class="docutils literal notranslate"><span class="pre">koffi.alignof(type)</span></code> to get the alignment of a type</p></li>
933
- <li><p><code class="docutils literal notranslate"><span class="pre">koffi.introspect(type)</span></code> to get the definition of a type in an object containing: name, primitive, size, alignment, members (structs), reference (array, pointer) and length (array)</p></li>
934
- <li><p><code class="docutils literal notranslate"><span class="pre">koffi.resolve(type)</span></code> to get the resolved type object from a type string</p></li>
935
- </ul>
936
- <div class="admonition note">
937
- <p class="admonition-title">Note</p>
938
- <p>The value returned by <code class="docutils literal notranslate"><span class="pre">introspect()</span></code> has <strong>changed in version 2.0</strong>.</p>
939
- <p>In Koffi 1.x, it could only be used with struct types and returned the object passed to koffi.struct() with the member names and types.</p>
940
- <p>Consult the <a class="reference internal" href="changes"><span class="doc std std-doc">migration guide</span></a> for more information.</p>
941
- </div>
942
- <p>Just like before, you can refer to primitive types by their name or through <code class="docutils literal notranslate"><span class="pre">koffi.types</span></code>:</p>
943
- <div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="c1">// These two lines do the same:</span>
944
- <span class="linenos">2</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">koffi</span><span class="p">.</span><span class="nx">sizeof</span><span class="p">(</span><span class="s1">&#39;long&#39;</span><span class="p">));</span>
945
- <span class="linenos">3</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">koffi</span><span class="p">.</span><span class="nx">sizeof</span><span class="p">(</span><span class="nx">koffi</span><span class="p">.</span><span class="nx">types</span><span class="p">.</span><span class="kr">long</span><span class="p">));</span>
946
- </pre></div>
947
- </div>
948
- </section>
949
- <section id="type-aliases">
950
- <h3>Type aliases<a class="headerlink" href="#type-aliases" title="Permalink to this heading">#</a></h3>
951
- <p><em>New in Koffi 2.0</em></p>
952
- <p>You can alias a type with <code class="docutils literal notranslate"><span class="pre">koffi.alias(name,</span> <span class="pre">type)</span></code>. Aliased types are completely equivalent.</p>
953
- </section>
954
- </section>
955
- </section>
956
-
957
- </article>
958
- </div>
959
- <footer>
960
-
961
- <div class="related-pages">
962
- <a class="next-page" href="functions">
963
- <div class="page-info">
964
- <div class="context">
965
- <span>Next</span>
966
- </div>
967
- <div class="title">Functions</div>
968
- </div>
969
- <svg><use href="#svg-arrow-right"></use></svg>
970
- </a>
971
- <a class="prev-page" href="start">
972
- <svg><use href="#svg-arrow-right"></use></svg>
973
- <div class="page-info">
974
- <div class="context">
975
- <span>Previous</span>
976
- </div>
977
-
978
- <div class="title">Quick start</div>
979
-
980
- </div>
981
- </a>
982
- </div>
983
- <div class="bottom-of-page">
984
- <div class="left-details">
985
- <div class="copyright">
986
- Copyright &#169; 2022, Niels Martignène
987
- </div>
988
- Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
989
-
990
- <a href="https://github.com/pradyunsg/furo">Furo</a>
991
-
992
- </div>
993
- <div class="right-details">
994
- <div class="icons">
995
-
996
- </div>
997
- </div>
998
- </div>
999
-
1000
- </footer>
1001
- </div>
1002
- <aside class="toc-drawer">
1003
-
1004
-
1005
- <div class="toc-sticky toc-scroll">
1006
- <div class="toc-title-container">
1007
- <span class="toc-title">
1008
- Contents
1009
- </span>
1010
- </div>
1011
- <div class="toc-tree-container">
1012
- <div class="toc-tree">
1013
- <ul>
1014
- <li><a class="reference internal" href="#">Data types</a><ul>
1015
- <li><a class="reference internal" href="#primitive-types">Primitive types</a><ul>
1016
- <li><a class="reference internal" href="#standard-types">Standard types</a></li>
1017
- <li><a class="reference internal" href="#endian-sensitive-types">Endian-sensitive types</a></li>
1018
- </ul>
1019
- </li>
1020
- <li><a class="reference internal" href="#struct-types">Struct types</a><ul>
1021
- <li><a class="reference internal" href="#struct-definition">Struct definition</a></li>
1022
- <li><a class="reference internal" href="#opaque-types">Opaque types</a></li>
1023
- </ul>
1024
- </li>
1025
- <li><a class="reference internal" href="#pointer-types">Pointer types</a><ul>
1026
- <li><a class="reference internal" href="#struct-pointers">Struct pointers</a></li>
1027
- <li><a class="reference internal" href="#named-pointer-types">Named pointer types</a></li>
1028
- <li><a class="reference internal" href="#pointers-to-primitive-types">Pointers to primitive types</a></li>
1029
- </ul>
1030
- </li>
1031
- <li><a class="reference internal" href="#array-types">Array types</a><ul>
1032
- <li><a class="reference internal" href="#fixed-size-c-arrays">Fixed-size C arrays</a></li>
1033
- <li><a class="reference internal" href="#fixed-size-string-buffers">Fixed-size string buffers</a></li>
1034
- <li><a class="reference internal" href="#array-pointers-dynamic-arrays">Array pointers (dynamic arrays)</a></li>
1035
- </ul>
1036
- </li>
1037
- <li><a class="reference internal" href="#disposable-types">Disposable types</a></li>
1038
- <li><a class="reference internal" href="#utility-functions">Utility functions</a><ul>
1039
- <li><a class="reference internal" href="#type-introspection">Type introspection</a></li>
1040
- <li><a class="reference internal" href="#type-aliases">Type aliases</a></li>
1041
- </ul>
1042
- </li>
1043
- </ul>
1044
- </li>
1045
- </ul>
1046
-
1047
- </div>
1048
- </div>
1049
- </div>
1050
-
1051
-
1052
- </aside>
1053
- </div>
1054
- </div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
1055
- <script src="_static/jquery.js"></script>
1056
- <script src="_static/underscore.js"></script>
1057
- <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
1058
- <script src="_static/doctools.js"></script>
1059
- <script src="_static/scripts/furo.js"></script>
1060
- </body>
1061
- </html>