koffi 2.0.1 → 2.1.0-beta.1

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 (78) hide show
  1. package/CMakeLists.txt +1 -8
  2. package/benchmark/atoi_koffi.js +12 -8
  3. package/benchmark/atoi_napi.js +12 -8
  4. package/benchmark/atoi_node_ffi.js +11 -10
  5. package/benchmark/raylib_cc.cc +12 -9
  6. package/benchmark/raylib_koffi.js +15 -13
  7. package/benchmark/raylib_node_ffi.js +15 -13
  8. package/benchmark/raylib_node_raylib.js +14 -11
  9. package/build/qemu/2.1.0-beta.1/koffi_darwin_arm64.tar.gz +0 -0
  10. package/build/qemu/2.1.0-beta.1/koffi_darwin_x64.tar.gz +0 -0
  11. package/build/qemu/2.1.0-beta.1/koffi_freebsd_arm64.tar.gz +0 -0
  12. package/build/qemu/2.1.0-beta.1/koffi_freebsd_ia32.tar.gz +0 -0
  13. package/build/qemu/2.1.0-beta.1/koffi_freebsd_x64.tar.gz +0 -0
  14. package/build/qemu/2.1.0-beta.1/koffi_linux_arm32hf.tar.gz +0 -0
  15. package/build/qemu/2.1.0-beta.1/koffi_linux_arm64.tar.gz +0 -0
  16. package/build/qemu/2.1.0-beta.1/koffi_linux_ia32.tar.gz +0 -0
  17. package/build/qemu/2.1.0-beta.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  18. package/build/qemu/2.1.0-beta.1/koffi_linux_x64.tar.gz +0 -0
  19. package/build/qemu/2.1.0-beta.1/koffi_openbsd_ia32.tar.gz +0 -0
  20. package/build/qemu/2.1.0-beta.1/koffi_openbsd_x64.tar.gz +0 -0
  21. package/build/qemu/2.1.0-beta.1/koffi_win32_arm64.tar.gz +0 -0
  22. package/build/qemu/2.1.0-beta.1/koffi_win32_ia32.tar.gz +0 -0
  23. package/build/qemu/2.1.0-beta.1/koffi_win32_x64.tar.gz +0 -0
  24. package/doc/changes.md +12 -8
  25. package/doc/dist/doctrees/changes.doctree +0 -0
  26. package/doc/dist/doctrees/environment.pickle +0 -0
  27. package/doc/dist/doctrees/functions.doctree +0 -0
  28. package/doc/dist/doctrees/index.doctree +0 -0
  29. package/doc/dist/doctrees/types.doctree +0 -0
  30. package/doc/dist/html/_sources/changes.md.txt +12 -8
  31. package/doc/dist/html/_sources/functions.md.txt +4 -4
  32. package/doc/dist/html/_sources/types.md.txt +69 -34
  33. package/doc/dist/html/benchmarks.html +1 -1
  34. package/doc/dist/html/changes.html +44 -33
  35. package/doc/dist/html/contribute.html +1 -1
  36. package/doc/dist/html/functions.html +7 -7
  37. package/doc/dist/html/genindex.html +1 -1
  38. package/doc/dist/html/index.html +3 -3
  39. package/doc/dist/html/memory.html +1 -1
  40. package/doc/dist/html/objects.inv +0 -0
  41. package/doc/dist/html/platforms.html +2 -2
  42. package/doc/dist/html/search.html +1 -1
  43. package/doc/dist/html/searchindex.js +1 -1
  44. package/doc/dist/html/start.html +1 -1
  45. package/doc/dist/html/types.html +77 -40
  46. package/doc/functions.md +4 -4
  47. package/doc/types.md +68 -33
  48. package/package.json +2 -2
  49. package/qemu/qemu.js +1 -1
  50. package/src/call.cc +42 -26
  51. package/src/call.hh +15 -3
  52. package/src/ffi.cc +70 -13
  53. package/src/ffi.hh +7 -0
  54. package/src/index.js +4 -2
  55. package/src/parser.cc +3 -5
  56. package/src/util.cc +44 -1
  57. package/src/util.hh +4 -0
  58. package/test/async.js +1 -2
  59. package/test/callbacks.js +2 -3
  60. package/test/misc.c +21 -1
  61. package/test/raylib.js +1 -1
  62. package/test/sqlite.js +3 -3
  63. package/test/sync.js +27 -3
  64. package/build/qemu/2.0.1/koffi_darwin_arm64.tar.gz +0 -0
  65. package/build/qemu/2.0.1/koffi_darwin_x64.tar.gz +0 -0
  66. package/build/qemu/2.0.1/koffi_freebsd_arm64.tar.gz +0 -0
  67. package/build/qemu/2.0.1/koffi_freebsd_ia32.tar.gz +0 -0
  68. package/build/qemu/2.0.1/koffi_freebsd_x64.tar.gz +0 -0
  69. package/build/qemu/2.0.1/koffi_linux_arm32hf.tar.gz +0 -0
  70. package/build/qemu/2.0.1/koffi_linux_arm64.tar.gz +0 -0
  71. package/build/qemu/2.0.1/koffi_linux_ia32.tar.gz +0 -0
  72. package/build/qemu/2.0.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  73. package/build/qemu/2.0.1/koffi_linux_x64.tar.gz +0 -0
  74. package/build/qemu/2.0.1/koffi_openbsd_ia32.tar.gz +0 -0
  75. package/build/qemu/2.0.1/koffi_openbsd_x64.tar.gz +0 -0
  76. package/build/qemu/2.0.1/koffi_win32_arm64.tar.gz +0 -0
  77. package/build/qemu/2.0.1/koffi_win32_ia32.tar.gz +0 -0
  78. package/build/qemu/2.0.1/koffi_win32_x64.tar.gz +0 -0
@@ -1 +1 @@
1
- Search.setIndex({"docnames": ["benchmarks", "changes", "contribute", "functions", "index", "memory", "platforms", "start", "types"], "filenames": ["benchmarks.md", "changes.md", "contribute.md", "functions.md", "index.rst", "memory.md", "platforms.md", "start.md", "types.md"], "titles": ["Benchmarks", "Changelog", "Contributing", "Functions", "Koffi 2.0.0", "Memory usage", "Requirements", "Quick start", "Data types"], "terms": {"here": [0, 2, 3, 4, 8], "quick": [0, 4], "execut": [0, 3], "time": [0, 2, 3, 5, 7], "koffi": [0, 2, 3, 5, 6, 8], "call": [0, 1, 4, 5, 6, 7, 8], "three": [0, 7, 8], "where": [0, 3, 8], "compar": 0, "theoret": 0, "ideal": 0, "ffi": [0, 1, 3, 4, 7], "implement": [0, 3, 8], "approxim": [0, 8], "pre": 0, "compil": [0, 1, 6], "static": [0, 3], "n": [0, 2, 4, 6, 7, 8], "api": [0, 1, 2, 3, 4, 6, 7, 8], "glue": 0, "code": [0, 1, 3, 4, 5], "The": [0, 1, 2, 3, 4, 5, 6, 7, 8], "first": [0, 1, 2, 3, 7, 8], "base": [0, 3, 4, 8], "second": [0, 3, 7, 8], "third": 0, "These": [0, 2, 3, 8], "ar": [0, 1, 2, 3, 5, 6, 7, 8], "detail": 0, "explain": 0, "below": [0, 1, 2, 3, 7, 8], "node": [0, 1, 2, 3, 4, 7], "napi": 0, "present": 0, "were": [0, 1, 3, 8], "measur": 0, "my": [0, 2], "machin": [0, 2], "intel": 0, "core": 0, "i5": 0, "4460": 0, "thi": [0, 1, 2, 3, 4, 7, 8], "test": [0, 1, 4, 6], "around": [0, 5, 8], "repeat": 0, "simpl": [0, 2, 3, 8], "standard": [0, 3, 8], "c": [0, 1, 2, 4, 5, 6, 7], "function": [0, 1, 2, 4, 7], "ha": [0, 2, 3, 8], "one": [0, 2, 3, 5, 7, 8], "refer": [0, 4, 8], "through": [0, 1, 3, 8], "an": [0, 1, 3, 5, 8], "modul": [0, 1, 4], "close": [0, 8], "limit": [0, 1, 3], "perfect": 0, "overhead": [0, 4], "js": [0, 1, 2, 4, 5, 8], "us": [0, 1, 2, 3, 4, 5, 6, 7, 8], "offici": [0, 2, 6], "iter": [0, 8], "rel": 0, "perform": [0, 4, 8], "rand_napi": 0, "644": 0, "ns": 0, "x1": 0, "00": 0, "ref": 0, "rand_koffi": 0, "950": 0, "x0": 0, "68": 0, "48": 0, "rand_node_ffi": 0, "30350": 0, "02": 0, "4613": 0, "becaus": [0, 2, 3, 8], "pretti": [0, 2], "small": [0, 3, 4], "clearli": 0, "visibl": 0, "similar": [0, 3], "which": [0, 1, 2, 3, 6, 7], "take": [0, 3, 8], "string": [0, 1, 3, 5, 7], "paramet": [0, 1, 7, 8], "javascript": [0, 4, 8], "v8": [0, 3, 5], "convers": [0, 1, 4, 8], "slow": [0, 2], "heavi": 0, "atoi_napi": 0, "1104": 0, "atoi_koffi": 0, "1778": 0, "62": 0, "61": 0, "atoi_node_ffi": 0, "125300": 0, "009": 0, "11250": 0, "cpu": 0, "imag": 0, "draw": 0, "much": [0, 2], "heavier": 0, "than": [0, 1, 5], "thu": [0, 3], "reduc": [0, 1], "In": [0, 1, 3, 8], "baselin": 0, "full": [0, 2, 8], "version": [0, 1, 3, 4, 6, 8], "nativ": [0, 3], "wrapper": [0, 2], "raylib_cc": 0, "215": 0, "7": [0, 7], "\u00b5s": 0, "20": 0, "17": [0, 6], "raylib_node_raylib": 0, "258": 0, "9": 0, "raylib_koffi": 0, "311": 0, "6": [0, 3, 7, 8], "83": 0, "raylib_node_ffi": 0, "928": 0, "4": [0, 8], "28": 0, "259": 0, "965": 0, "1248": 0, "77": 0, "29": 0, "41500": 0, "4203": 0, "1393": 0, "2246": 0, "157550": 0, "11210": 0, "without": [0, 2, 6], "ani": [0, 2, 3, 4, 5, 8], "211": 0, "8": [0, 2, 3, 4, 6, 7, 8], "25": 0, "264": 0, "318": 0, "21": 0, "1146": 0, "2": [0, 3, 5, 6, 8], "23": 0, "334": 0, "pleas": [0, 5], "note": [0, 2, 5, 8], "order": [0, 1, 2, 3], "get": [0, 1, 2, 3, 5, 7, 8], "fair": 0, "number": [0, 1, 3, 5, 8], "wa": [0, 1], "recompil": 0, "clang": [0, 1, 8], "cl": 0, "befor": [0, 1, 2, 8], "follow": [0, 1, 2, 3, 6, 8], "command": [0, 2], "cd": [0, 2], "node_modul": 0, "rmdir": 0, "s": [0, 1, 3, 8], "q": [0, 2], "bin": 0, "build": [0, 1, 4, 6, 8], "npx": 0, "cmake": [0, 2], "t": [0, 3], "clangcl": 0, "open": [0, 1, 3, 8], "consol": [0, 1, 3, 5, 8], "go": [0, 2], "cnoke": [0, 2], "do": [0, 2, 3, 7, 8], "anyth": 0, "els": [0, 8], "all": [0, 1, 3, 6, 8], "made": [0, 1, 3, 5, 8], "built": 0, "binari": [0, 1, 2, 6], "prefer": [0, 2, 3], "onc": [0, 2, 3, 5, 7, 8], "everyth": [0, 2], "readi": 0, "main": [1, 3], "fix": [1, 2, 4], "prebuild": 1, "compat": [1, 2, 3], "electron": 1, "window": [1, 3, 4, 6], "x64": 1, "chang": [1, 2, 3, 5, 8], "prevent": [1, 8], "callback": [4, 5, 6, 8], "reus": 1, "beyond": 1, "add": [1, 2, 8], "bti": 1, "support": [1, 2, 3, 4, 8], "aaarch64": 1, "platform": [1, 3, 4, 5, 8], "except": [1, 2], "other": [1, 3, 8], "harmon": 1, "few": [1, 8], "error": [1, 3, 8], "messag": [1, 7], "crash": [1, 3], "when": [1, 2, 3, 5, 8], "insid": [1, 3], "struct": [1, 2, 4, 5, 7], "null": [1, 3, 7, 8], "record": 1, "member": [1, 3, 8], "intptr_t": [1, 8], "uintptr_t": [1, 8], "primit": [1, 3, 4], "type": [2, 3, 4, 7], "str": [1, 3, 7, 8], "str16": [1, 3, 7, 8], "alias": 1, "string16": [1, 8], "variou": [1, 2], "document": [1, 8], "improv": [1, 2], "instal": [1, 2, 4, 6], "15": [1, 6, 8], "system": [1, 2, 7], "bug": [1, 4], "detect": [1, 3], "incompat": 1, "linux": [1, 2, 4, 6], "memori": [1, 3, 4, 8], "leak": [1, 3, 8], "mani": [1, 3, 8], "async": [1, 3], "run": [1, 3, 4, 5, 7], "configur": [1, 2], "maximum": [1, 3, 5], "max_async_cal": [1, 5], "default": [1, 2, 3, 4, 8], "stack": [1, 5], "heap": [1, 5, 8], "size": [1, 2, 4, 5], "possibl": [1, 2, 8], "openbsd": [1, 6], "i386": 1, "void": [1, 3, 7, 8], "misconvers": 1, "sign": [1, 8], "integ": [1, 3, 8], "return": [1, 3, 8], "valu": [1, 4, 7, 8], "unsign": [1, 3, 7, 8], "empti": 1, "signatur": 1, "disabl": [1, 2], "unsaf": 1, "optim": [1, 2], "14": [1, 6, 8], "mode": [1, 3], "grace": 1, "degrad": 1, "older": [1, 6], "toolchain": 1, "debian": [1, 2], "prebuilt": [1, 2, 6], "rebuild": 1, "happen": [1, 3, 8], "fail": [1, 2, 3, 8], "load": [1, 3, 7, 8], "major": 1, "expand": 1, "move": 1, "http": [1, 2, 4], "dev": [1, 2], "arrai": [1, 2, 4], "typedarrai": [1, 8], "pointer": [1, 3, 4], "argument": [1, 3, 7, 8], "input": [1, 3, 8], "output": [1, 7, 8], "mix": [1, 2, 8], "convert": [1, 3, 8], "instead": [1, 2, 8], "hint": [1, 8], "char": [1, 3, 7, 8], "char16": [1, 8], "char16_t": [1, 8], "definit": [1, 4, 8], "long": [1, 8], "llp64": [1, 8], "model": 1, "restrict": [1, 2, 3], "automat": [1, 3, 8], "float": [1, 3, 6, 8], "point": [1, 8], "abi": [1, 2, 3, 6, 8], "arm32": [1, 6], "risc": [1, 6], "v": [1, 6], "forbid": 1, "duplic": 1, "name": [1, 2, 3, 8], "new": [1, 3, 5, 8], "featur": [1, 4], "arm64": [1, 2, 6], "now": [1, 2, 3, 7, 8], "A": [1, 3, 6, 8], "maco": [1, 2, 6], "m1": 1, "includ": [1, 2, 3, 6, 8], "entri": 1, "sinc": [1, 4], "can": [1, 2, 3, 4, 5, 6, 7, 8], "cdecl": [1, 3, 6], "stdcall": [1, 3, 6, 7], "64": [1, 3, 5, 6, 8], "lp64d": [1, 6], "lp64": [1, 6, 8], "untest": [1, 6], "expos": [1, 8], "set": [1, 2, 4], "usag": [1, 4], "synchron": [1, 3, 5], "asynchron": [1, 5], "transpar": [1, 8], "between": [1, 3], "buffer": [1, 8], "tent": 1, "excess": 1, "align": [1, 8], "x86": [1, 3, 6, 7], "potenti": [1, 8], "problem": 1, "big": [1, 3, 5, 8], "int64_t": [1, 7, 8], "uint64_t": [1, 8], "layout": 1, "push": [1, 8], "pop": 1, "issu": [1, 3], "incomplet": 1, "buggi": 1, "hfa": [1, 2], "caus": [1, 3], "miss": [1, 2], "map_stack": 1, "flag": 1, "non": [1, 3, 8], "sens": 1, "intern": [1, 8], "fals": [1, 8], "normal": [1, 5, 8], "make": [1, 2, 3], "sure": [1, 2], "we": [1, 2, 8], "have": [1, 2, 3, 7, 8], "redzon": 1, "architectur": [1, 2, 3, 4, 6, 8], "slower": 1, "alloc": [1, 5, 8], "object": [1, 2, 3, 5, 8], "repositori": 2, "luigi": [2, 4], "monorepo": 2, "contain": [2, 8], "multipl": [1, 2], "project": 2, "idea": 2, "github": [2, 4], "com": [2, 4], "koromix": [2, 4], "provid": [2, 3, 8], "packag": [1, 2, 6], "npm": [2, 6, 7], "archiv": 2, "so": [2, 3, 7, 8], "most": [2, 3, 8], "case": [2, 3, 8], "should": 2, "If": [2, 3, 8], "you": [1, 2, 3, 4, 6, 7, 8], "want": [2, 7], "hack": 2, "specif": [1, 2, 5], "instruct": [2, 3], "start": [2, 3, 4], "clone": 2, "git": 2, "As": 2, "said": 2, "monorepositori": 2, "conta": 2, "henc": 2, "depend": [2, 3, 8], "met": 2, "desktop": 2, "develop": 2, "workload": 2, "visual": 2, "studio": 2, "2022": 2, "2019": 2, "tool": 2, "option": [2, 3, 4, 8], "compon": 2, "meta": 2, "12": [2, 6], "later": [2, 3, 4, 6], "done": [2, 3, 8], "benchmark": [2, 4], "directori": [2, 8], "what": 2, "gcc": 2, "g": [2, 3, 8], "3": [2, 4, 6, 8], "newer": [1, 2, 3, 6], "gnu": [2, 4], "81": 2, "emul": 2, "acceler": 2, "qemu": 2, "need": [1, 2, 3, 8], "even": 2, "gui": 2, "ubuntu": 2, "directli": [1, 2, 3, 5, 8], "licens": 2, "reason": [2, 8], "thei": [2, 3, 8], "avail": [2, 4, 5], "file": [1, 2, 3, 8], "For": [1, 2, 3, 5, 6, 8], "exampl": [2, 4, 8], "wget": 2, "o": [2, 8], "qemu_debian_arm64": 2, "tar": 2, "zst": 2, "zstd": 2, "d": [2, 3, 8], "xv": 2, "sha256sum": 2, "ignor": [2, 3, 8], "registri": 2, "txt": 2, "disk": 2, "content": [2, 8], "mai": [1, 2, 3], "each": [2, 3, 8], "checksum": 2, "been": [2, 3], "least": [2, 5], "And": [2, 7], "sever": [2, 3], "help": 2, "patient": 2, "ccach": 2, "subsequ": [2, 3, 5], "step": 2, "more": [1, 2, 3, 4, 5, 6, 8], "toler": 2, "By": [2, 3, 8], "stop": 2, "But": [2, 3, 8], "ahead": 2, "shut": 2, "down": 2, "again": 2, "also": [2, 3, 8], "subset": 2, "cycl": 2, "debian_x64": 2, "debian_i386": 2, "separ": 2, "shutdown": 2, "final": [2, 8], "join": 2, "ssh": 2, "shortcut": [2, 3], "some": [1, 2, 3, 8], "debug": 2, "manual": [2, 3], "procedur": [2, 3], "vnc": 2, "server": 2, "local": [2, 7], "access": [2, 3], "displai": 2, "krdc": 2, "viewer": 2, "info": 2, "port": 2, "plan": 2, "necessarili": 2, "pass": [1, 2, 3, 8], "avoid": [2, 3, 8], "properti": 2, "helper": 2, "autom": 2, "aarch64": [2, 6], "how": [2, 3, 4, 8], "thank": [2, 8], "appl": 2, "creat": [2, 3, 8], "real": 2, "world": [2, 3, 7, 8], "librari": [2, 3, 7, 8], "raylib": 2, "sqlite": [2, 3], "libsodium": 2, "illustr": [1, 2, 3, 7, 8], "parser": [1, 2, 3], "wai": [1, 2, 3, 7, 8], "encod": [2, 8], "decod": 2, "byte": [2, 5, 8], "union": 2, "powerpc": 2, "power9": 2, "assembl": [2, 5], "unwind": 2, "cfi": 2, "direct": [2, 8], "better": 2, "experi": 2, "program": [2, 3, 4], "It": [2, 3, 7, 8], "addon": 2, "interact": 2, "person": 2, "goe": 2, "rather": 2, "like": [1, 2, 7, 8], "care": [2, 3, 8], "templat": 2, "mainli": 2, "littl": 2, "orient": [2, 8], "i": [2, 8], "strongli": 2, "tag": 2, "over": 2, "inherit": 2, "virtual": 2, "method": 2, "To": 3, "declar": [3, 7, 8], "share": [3, 7, 8], "filenam": [3, 8], "const": [1, 3, 7, 8], "requir": [3, 4, 7, 8], "lib": [1, 3, 7, 8], "path": [3, 8], "extens": 3, "dll": [3, 7, 8], "dylib": 3, "etc": 3, "from": [3, 4, 6, 8], "two": [1, 3, 5, 8], "inspir": 3, "specifi": [3, 8], "its": [3, 8], "mangl": 3, "ellipsi": 3, "last": [3, 8], "printf": [3, 7], "func": [1, 3, 7, 8], "int": [1, 3, 7, 8], "atoi": 3, "tri": 3, "convent": [6, 7], "see": [3, 4, 8], "section": [3, 8], "inform": [1, 3, 4, 8], "subject": 3, "shown": [1, 3, 8], "fmt": 3, "onli": [1, 3, 6, 8], "per": 3, "process": 3, "32": 3, "bit": [3, 8], "form": 3, "descript": [3, 5], "__stdcall": [3, 8], "within": 3, "win32": [3, 7, 8], "fastcal": [3, 6], "__fastcal": 3, "rare": [3, 8], "ecx": 3, "edx": 3, "thiscal": [3, 6], "__thiscal": 3, "safe": 3, "simpli": [3, 8], "find": [3, 4, 7, 8], "show": [3, 7, 8], "user32": [3, 7], "equival": [1, 3, 8], "messageboxa_1": 3, "messageboxa": [3, 7], "uint": [3, 7, 8], "messageboxa_2": 3, "hwnd": 3, "text": 3, "caption": 3, "err": 3, "re": 3, "libc": [3, 7], "1257": 3, "log": [1, 3, 5, 8], "result": [3, 7, 8], "hello": [1, 3, 7, 8], "print": [3, 7, 8], "worker": 3, "your": [1, 3, 4], "respons": 3, "deal": [3, 8], "data": [3, 4], "multi": 3, "easili": 3, "style": [3, 4], "promis": 3, "util": [3, 4], "promisifi": 3, "cannot": [3, 5, 8], "must": [1, 3, 8], "addit": [3, 8], "expect": [3, 6, 8], "5": [3, 8], "doubl": [3, 6, 8], "THE": 3, "end": 3, "On": 3, "forward": [3, 6], "howev": [3, 5, 8], "simplic": 3, "semant": [3, 8], "marshal": 3, "out": [3, 8], "e": [3, 8], "timev": [3, 7], "inout": 3, "dual": 3, "same": [3, 5, 8], "msdn": 3, "qualifi": 3, "_out_": [1, 3, 7, 8], "_inout_": [3, 8], "posix": 3, "gettimeofdai": [3, 7], "tv_sec": [3, 7], "tv_usec": [3, 7], "timezon": [3, 7], "tz_minuteswest": [3, 7], "tz_dsttime": [3, 7], "tv": [3, 7], "tz": [3, 7], "let": [1, 3, 5, 7, 8], "databas": [1, 3], "sqlite3_db": [], "copi": [3, 8], "after": [1, 3, 8], "sqlite3_open_v2": [1, 3], "sqlite3_close_v2": [1, 3], "sqlite_open_readwrit": [1, 3], "0x2": [1, 3], "sqlite_open_cr": [1, 3], "0x4": [1, 3, 7], "db": [1, 3], "0": [3, 6, 8], "throw": [1, 3, 8], "while": [3, 8], "doe": [3, 5, 8], "know": 3, "someth": [3, 8], "freed": [3, 5], "matter": 3, "explicitli": [3, 8], "fclose": [1, 3, 8], "them": [1, 3, 8], "implicitli": 3, "lose": 3, "origin": 3, "dispos": [1, 3, 4], "deriv": 3, "anoth": [3, 7, 8], "differ": [1, 3, 6, 8], "being": 3, "anymor": 3, "omit": [3, 8], "anonym": [3, 8], "free": [3, 4, 8], "ptr": [1, 3, 8], "under": [3, 4], "hood": 3, "anonheapstr": 3, "namedheapstr": 3, "heapstr": 3, "thing": 3, "usabl": [1, 3, 8], "explicitfre": 3, "heapstr16": 3, "strdup": 3, "asprintf": [], "either": [3, 4, 8], "Be": 3, "crt": 3, "msvcrt": 3, "could": [3, 8], "malloc": [3, 8], "undefin": [3, 8], "behavior": [1, 3, 8], "With": 3, "noth": 3, "examplecallback": 3, "sum": [3, 8], "adddoublefloat": 3, "f": [3, 8], "1": [3, 4, 5, 6, 7, 8], "x": [3, 6, 8], "defin": [1, 3, 8], "obscur": [1, 3, 8], "underli": [1, 3, 8], "callit": [1, 3], "callbacktyp": [1, 3], "becom": [1, 3], "predefin": 3, "trampolin": 3, "gener": [3, 4, 8], "runtim": 3, "harden": 3, "w": 3, "migit": 3, "pax": 3, "mprotect": 3, "impos": 3, "durat": 3, "distinguish": [3, 8], "invalid": 3, "though": 3, "thrown": [1, 3], "guarante": 3, "don": 3, "special": 3, "unregist": 3, "exist": 3, "qsort": 3, "progress": 3, "sqlite3_exec": 3, "part": [3, 8], "h": [1, 3, 8], "transfertoj": [1, 3], "ag": [1, 3], "cb": [1, 3], "buf": [1, 3], "snprintf": [1, 3], "sizeof": [1, 3, 8], "fake": 3, "transfercallback": [1, 3], "ret": [1, 3, 7], "niel": [1, 3], "27": [1, 3], "42": [1, 3, 8], "handler": 3, "event": 3, "fopencooki": 3, "funopen": 3, "releas": 3, "slot": 3, "16": [3, 6, 7, 8], "failur": [3, 8], "registr": 3, "delai": 3, "g_cb1": 3, "g_cb2": 3, "registerfunct": 3, "cb1": 3, "cb2": 3, "sayit": 3, "getcallback": 3, "printcallback": 3, "kyoto": 3, "receiv": 3, "yourself": [3, 8], "try": [3, 8], "catch": 3, "precis": [3, 6], "intepret": 3, "lead": 3, "mess": [3, 8], "ve": 3, "warn": 3, "fast": 4, "easi": 4, "low": 4, "aggreg": 4, "both": [4, 8], "well": 4, "popular": 4, "os": [4, 6, 8], "combin": [4, 6], "recent": [4, 6], "page": [4, 5, 8], "sourc": [4, 6], "subdirectori": 4, "introspect": [], "gotcha": 4, "thread": 4, "safeti": 4, "work": [1, 4], "x86_64": [4, 6], "contribut": 4, "request": 4, "todo": 4, "list": [1, 4, 8], "changelog": 4, "softwar": 4, "redistribut": 4, "modifi": [4, 8], "term": 4, "affero": 4, "public": 4, "publish": 4, "foundat": 4, "www": 4, "org": 4, "prealloc": 5, "block": 5, "One": 5, "construct": 5, "assign": [5, 8], "regist": [1, 5, 8], "mib": 5, "unless": 5, "veri": 5, "extra": 5, "dure": 5, "engin": 5, "might": 5, "config": 5, "obj": 5, "appli": [5, 8], "true": [5, 8], "unus": 5, "resid": 5, "still": [1, 5], "finish": 5, "resident_async_pool": 5, "left": 5, "There": 5, "sync_stack_s": 5, "sync_heap_s": 5, "async_stack_s": 5, "256": 5, "kib": 5, "async_heap_s": 5, "512": 5, "pool": 5, "ongo": 5, "22": 6, "nvm": 6, "distribut": 6, "moment": 6, "isa": 6, "freebsd": 6, "ia32": 6, "ye": 6, "amd64": 6, "le": [6, 8], "probabl": [3, 6], "fulli": 6, "green": 6, "check": 6, "mark": 6, "mean": [6, 8], "ms": 6, "hard": 6, "vfp": 6, "coprocessor": 6, "softfp": 6, "soft": 6, "theori": 6, "lp64f": 6, "prototyp": [1, 7], "languag": 7, "syntax": [1, 7], "localtime_r": 7, "current": [7, 8], "time_t": 7, "tm": 7, "tm_sec": 7, "tm_min": 7, "tm_hour": 7, "tm_mdai": 7, "tm_mon": 7, "tm_year": 7, "tm_wdai": 7, "tm_ydai": 7, "tm_isdst": 7, "format": 7, "variad": 7, "02d": 7, "target": 7, "messagebox": 7, "user": [7, 8], "utf": [7, 8], "constant": 7, "mb_ok": 7, "0x0": 7, "mb_yesno": 7, "mb_iconquest": 7, "0x20": 7, "mb_iconinform": 7, "0x40": 7, "idok": 7, "idy": 7, "idno": 7, "messageboxw": 7, "box": 7, "allow": 8, "variat": 8, "enforc": 8, "signed": 8, "valid": 8, "int8": 8, "int8_t": 8, "uint8": 8, "uint8_t": 8, "uchar": 8, "int16": 8, "int16_t": 8, "uint16": 8, "uint16_t": 8, "short": 8, "int32": 8, "int32_t": 8, "uint32": 8, "uint32_t": [1, 8], "int64": 8, "uint64": 8, "longlong": 8, "ulonglong": 8, "float32": 8, "float64": 8, "accept": 8, "bigint": 8, "exce": 8, "rang": 8, "revers": 8, "boolean": 8, "bool": 8, "usual": 8, "ulong": 8, "intptr": 8, "width": 8, "uintptr": 8, "line": 8, "struct1": 8, "dummi": [1, 8], "struct2": 8, "vice": 8, "versa": 8, "unlik": 8, "typedef": 8, "b": 8, "d1": 8, "d2": 8, "rule": 8, "regard": 8, "pad": 8, "latter": 8, "function1": 8, "function2": 8, "differenti": 8, "purpos": 8, "import": 8, "fall": 8, "expens": 8, "stabil": 8, "dynam": 8, "termin": 8, "sentinel": 8, "length": 8, "lot": 8, "getcursorpo": 8, "retriev": 8, "cursor": 8, "posit": 8, "kernel32": 8, "y": 8, "po": 8, "kind": 8, "pair": 8, "dedic": 8, "delet": 8, "obviou": 8, "found": 8, "stdio": 8, "fopen": [1, 8], "manipul": 8, "fread": 8, "ftell": 8, "manag": [1, 8], "look": 8, "concatnewout": 8, "describ": 8, "builder": 8, "concaten": 8, "fizzbuzz": 8, "hidden": 8, "behind": 8, "destroi": 8, "concatnew": 8, "concatfre": 8, "fpic": 8, "wall": 8, "o2": 8, "stdlib": 8, "stdbool": 8, "errno": 8, "fragment": 8, "next": 8, "size_t": 8, "len": 8, "concat": 8, "total": 8, "fprintf": 8, "stderr": 8, "strerror": 8, "concatappend": 8, "frag": 8, "strlen": 8, "memcpi": 8, "concatbuild": 8, "r": 8, "stupid": 8, "30": 8, "buzz": 8, "fizz": 8, "infer": 8, "itself": 8, "translat": 8, "proper": 8, "notion": 8, "fat": 8, "calcul": 8, "stdint": 8, "computetotallength": 8, "just": 8, "findfirstfilew": 8, "findnextfilew": 8, "filetim": 8, "dwlowdatetim": 8, "dwhighdatetim": 8, "win32_find_data": 8, "dwfileattribut": 8, "ftcreationtim": 8, "ftlastaccesstim": 8, "ftlastwritetim": 8, "nfilesizehigh": 8, "nfilesizelow": 8, "dwreserved0": 8, "dwreserved1": 8, "cfilenam": 8, "260": 8, "calternatefilenam": 8, "dwfiletyp": 8, "obsolet": 8, "dwcreatortyp": 8, "wfinderflag": 8, "ushort": 8, "findfirstfil": 8, "findnextfil": 8, "findclos": 8, "getlasterror": 8, "dirnam": 8, "error_file_not_found": 8, "18": 8, "error_no_more_fil": 8, "among": 8, "variabl": 8, "invol": 8, "list1": 8, "list2": 8, "singl": [1, 8], "element": [1, 8], "store": 8, "addint": 8, "dest": 8, "36": 8, "degener": 8, "emb": 8, "correct": [3, 8], "uint8arrai": 8, "those": 8, "exactli": 8, "foo1": 8, "foo": 8, "a16": 8, "foo2": 8, "hypothet": 8, "returnfoo1": 8, "returnfoo": 8, "p": 8, "returnfoo2": 8, "int16arrai": 8, "fill": 8, "truncat": 8, "alwai": 8, "nul": 8, "ask": 8, "explor": 8, "alignof": 8, "about": 8, "caller": [], "yarn": 1, "broken": 1, "pars": 1, "incorrect": 1, "stream": [], "fp": 1, "touch": [], "wb": 1, "would": 1, "initi": 1, "structtyp": 1, "sqlite3": [1, 3], "histori": 4, "migrat": [3, 4, 8], "guid": [3, 4, 8], "given": 1, "transient": 1, "magic": 1, "instrospect": [], "consult": [1, 3, 8], "complex": 1, "outsid": 1, "minor": 1, "alia": [1, 8], "resolv": [1, 8], "correctli": 1, "break": 1, "complet": 8, "read": 8}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"benchmark": 0, "overview": [0, 4], "linux": [0, 7], "x86_64": 0, "rand": 0, "result": 0, "atoi": 0, "raylib": 0, "window": [0, 2, 7], "run": [0, 2], "changelog": 1, "koffi": [1, 4, 7], "1": 1, "3": 1, "9": 1, "8": 1, "7": 1, "6": 1, "5": 1, "4": 1, "2": [1, 4], "0": [1, 4], "contribut": 2, "bug": 2, "featur": 2, "request": 2, "build": 2, "from": 2, "sourc": 2, "other": 2, "platform": [2, 6], "test": 2, "todo": 2, "list": 2, "code": 2, "style": 2, "function": [3, 8], "call": 3, "definit": 3, "classic": 3, "syntax": 3, "c": [3, 8], "like": 3, "prototyp": 3, "synchron": [], "asynchron": 3, "variad": 3, "js": [3, 6], "convers": 3, "gotcha": 3, "output": 3, "paramet": 3, "struct": [3, 8], "exampl": [3, 7], "opaqu": [1, 3, 8], "handl": [1, 3, 8], "heap": 3, "alloc": 3, "valu": 3, "javascript": 3, "callback": [1, 3], "transient": 3, "regist": 3, "except": 3, "thread": 3, "safeti": 3, "tabl": 4, "content": 4, "licens": 4, "memori": 5, "usag": 5, "how": 5, "work": 5, "default": 5, "set": 5, "requir": 6, "node": 6, "support": 6, "quick": 7, "start": 7, "instal": 7, "small": 7, "data": 8, "type": [1, 8], "primit": 8, "pointer": 8, "arrai": 8, "fix": 8, "size": 8, "string": 8, "introspect": [1, 8], "convent": 3, "histori": 1, "12": 1, "11": 1, "10": 1, "migrat": 1, "guid": 1, "x": 1, "alias": 8, "dispos": 8, "util": 8}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 56}})
1
+ Search.setIndex({"docnames": ["benchmarks", "changes", "contribute", "functions", "index", "memory", "platforms", "start", "types"], "filenames": ["benchmarks.md", "changes.md", "contribute.md", "functions.md", "index.rst", "memory.md", "platforms.md", "start.md", "types.md"], "titles": ["Benchmarks", "Changelog", "Contributing", "Functions", "Koffi 2.0.1", "Memory usage", "Requirements", "Quick start", "Data types"], "terms": {"here": [0, 2, 3, 4, 8], "quick": [0, 4], "execut": [0, 3], "time": [0, 2, 3, 5, 7], "koffi": [0, 2, 3, 5, 6, 8], "call": [0, 1, 4, 5, 6, 7, 8], "three": [0, 7, 8], "where": [0, 3, 8], "compar": 0, "theoret": 0, "ideal": 0, "ffi": [0, 1, 3, 4, 7], "implement": [0, 3, 8], "approxim": [0, 8], "pre": 0, "compil": [0, 1, 6], "static": [0, 3], "n": [0, 2, 4, 6, 7, 8], "api": [0, 1, 2, 3, 4, 6, 7, 8], "glue": 0, "code": [0, 1, 3, 4, 5], "The": [0, 1, 2, 3, 4, 5, 6, 7, 8], "first": [0, 1, 2, 3, 7, 8], "base": [0, 3, 4, 8], "second": [0, 3, 7, 8], "third": 0, "These": [0, 2, 3, 8], "ar": [0, 1, 2, 3, 5, 6, 7, 8], "detail": 0, "explain": 0, "below": [0, 1, 2, 3, 7, 8], "node": [0, 1, 2, 3, 4, 7], "napi": 0, "present": 0, "were": [0, 1, 3, 8], "measur": 0, "my": [0, 2], "machin": [0, 2], "intel": 0, "core": 0, "i5": 0, "4460": 0, "thi": [0, 1, 2, 3, 4, 7, 8], "test": [0, 1, 4, 6], "around": [0, 5, 8], "repeat": 0, "simpl": [0, 2, 3, 8], "standard": [0, 3, 8], "c": [0, 1, 2, 4, 5, 6, 7], "function": [0, 1, 2, 4, 7], "ha": [0, 1, 2, 3, 8], "one": [0, 1, 2, 3, 5, 7, 8], "refer": [0, 4, 8], "through": [0, 1, 3, 8], "an": [0, 1, 3, 5, 8], "modul": [0, 1, 4], "close": [0, 8], "limit": [0, 1, 3], "perfect": 0, "overhead": [0, 4], "js": [0, 1, 2, 4, 5, 8], "us": [0, 1, 2, 3, 4, 5, 6, 7, 8], "offici": [0, 2, 6], "iter": [0, 8], "rel": 0, "perform": [0, 4, 8], "rand_napi": 0, "644": 0, "ns": 0, "x1": 0, "00": 0, "ref": 0, "rand_koffi": 0, "950": 0, "x0": 0, "68": 0, "48": 0, "rand_node_ffi": 0, "30350": 0, "02": 0, "4613": 0, "becaus": [0, 2, 3, 8], "pretti": [0, 2], "small": [0, 3, 4], "clearli": 0, "visibl": 0, "similar": [0, 3], "which": [0, 1, 2, 3, 6, 7, 8], "take": [0, 3, 8], "string": [0, 1, 3, 5, 7], "paramet": [0, 1, 7, 8], "javascript": [0, 4, 8], "v8": [0, 3, 5], "convers": [0, 1, 4, 8], "slow": [0, 2], "heavi": 0, "atoi_napi": 0, "1104": 0, "atoi_koffi": 0, "1778": 0, "62": 0, "61": 0, "atoi_node_ffi": 0, "125300": 0, "009": 0, "11250": 0, "cpu": 0, "imag": 0, "draw": 0, "much": [0, 2], "heavier": 0, "than": [0, 1, 5], "thu": [0, 3], "reduc": [0, 1], "In": [0, 1, 3, 8], "baselin": 0, "full": [0, 2, 8], "version": [0, 1, 3, 4, 6, 8], "nativ": [0, 3], "wrapper": [0, 2], "raylib_cc": 0, "215": 0, "7": [0, 7], "\u00b5s": 0, "20": 0, "17": [0, 6], "raylib_node_raylib": 0, "258": 0, "9": 0, "raylib_koffi": 0, "311": 0, "6": [0, 3, 7, 8], "83": 0, "raylib_node_ffi": 0, "928": 0, "4": [0, 8], "28": 0, "259": 0, "965": 0, "1248": 0, "77": 0, "29": 0, "41500": 0, "4203": 0, "1393": 0, "2246": 0, "157550": 0, "11210": 0, "without": [0, 2, 6, 8], "ani": [0, 2, 3, 4, 5, 8], "211": 0, "8": [0, 2, 3, 4, 6, 7, 8], "25": 0, "264": 0, "318": 0, "21": 0, "1146": 0, "2": [0, 3, 5, 6, 8], "23": 0, "334": 0, "pleas": [0, 5], "note": [0, 2, 5, 8], "order": [0, 1, 2, 3], "get": [0, 1, 2, 3, 5, 7, 8], "fair": 0, "number": [0, 1, 3, 5, 8], "wa": [0, 1], "recompil": 0, "clang": [0, 1, 8], "cl": 0, "befor": [0, 1, 2, 8], "follow": [0, 1, 2, 3, 6, 8], "command": [0, 2], "cd": [0, 2], "node_modul": 0, "rmdir": 0, "s": [0, 1, 3, 8], "q": [0, 2], "bin": 0, "build": [0, 1, 4, 6, 8], "npx": 0, "cmake": [0, 2], "t": [0, 3], "clangcl": 0, "open": [0, 1, 3, 8], "consol": [0, 1, 3, 5, 8], "go": [0, 2], "cnoke": [0, 2], "do": [0, 2, 3, 7, 8], "anyth": 0, "els": [0, 8], "all": [0, 1, 3, 6, 8], "made": [0, 1, 3, 5, 8], "built": 0, "binari": [0, 1, 2, 6], "prefer": [0, 2, 3], "onc": [0, 2, 3, 5, 7, 8], "everyth": [0, 2], "readi": 0, "main": [1, 3], "fix": [1, 2, 4], "prebuild": 1, "compat": [1, 2, 3], "electron": 1, "window": [1, 3, 4, 6], "x64": 1, "chang": [1, 2, 3, 5, 8], "prevent": [1, 8], "callback": [4, 5, 6, 8], "reus": 1, "beyond": 1, "add": [1, 2, 8], "bti": 1, "support": [1, 2, 3, 4, 8], "aaarch64": 1, "platform": [1, 3, 4, 5, 8], "except": [1, 2], "other": [1, 3, 8], "harmon": 1, "few": [1, 8], "error": [1, 3, 8], "messag": [1, 7], "crash": [1, 3], "when": [1, 2, 3, 5, 8], "insid": [1, 3], "struct": [1, 2, 4, 5, 7], "null": [1, 3, 7, 8], "record": 1, "member": [1, 3, 8], "intptr_t": [1, 8], "uintptr_t": [1, 8], "primit": [1, 3, 4], "type": [2, 4, 7], "str": [1, 3, 7, 8], "str16": [1, 3, 7, 8], "alias": 1, "string16": [1, 8], "variou": [1, 2], "document": [1, 8], "improv": [1, 2], "instal": [1, 2, 4, 6], "15": [1, 6, 8], "system": [1, 2, 7], "bug": [1, 4], "detect": [1, 3], "incompat": 1, "linux": [1, 2, 4, 6], "memori": [1, 3, 4, 8], "leak": [1, 3, 8], "mani": [1, 3, 8], "async": [1, 3], "run": [1, 3, 4, 5, 7], "configur": [1, 2], "maximum": [1, 3, 5], "max_async_cal": [1, 5], "default": [1, 2, 3, 4, 8], "stack": [1, 5], "heap": [1, 5, 8], "size": [1, 2, 4, 5], "possibl": [1, 2, 8], "openbsd": [1, 6], "i386": 1, "void": [1, 3, 7, 8], "misconvers": 1, "sign": [1, 8], "integ": [1, 3, 8], "return": [1, 3, 8], "valu": [1, 4, 7, 8], "unsign": [1, 3, 7, 8], "empti": 1, "signatur": 1, "disabl": [1, 2], "unsaf": 1, "optim": [1, 2], "14": [1, 6, 8], "mode": [1, 3], "grace": 1, "degrad": 1, "older": [1, 6], "toolchain": 1, "debian": [1, 2], "prebuilt": [1, 2, 6], "rebuild": 1, "happen": [1, 3, 8], "fail": [1, 2, 3, 8], "load": [1, 3, 7, 8], "major": 1, "expand": 1, "move": 1, "http": [1, 2, 4], "dev": [1, 2], "arrai": [1, 2, 4], "typedarrai": [1, 8], "pointer": [1, 3, 4], "argument": [1, 3, 7, 8], "input": [1, 3, 8], "output": [1, 7, 8], "mix": [1, 2, 8], "convert": [1, 3, 8], "instead": [1, 2, 8], "hint": [1, 8], "char": [1, 3, 7, 8], "char16": [1, 8], "char16_t": [1, 8], "definit": [1, 4], "long": [1, 8], "llp64": [1, 8], "model": 1, "restrict": [1, 2, 3], "automat": [1, 3, 8], "float": [1, 3, 6, 8], "point": [1, 8], "abi": [1, 2, 3, 6, 8], "arm32": [1, 6], "risc": [1, 6], "v": [1, 6], "forbid": 1, "duplic": 1, "name": [1, 2, 3], "new": [1, 3, 5, 8], "featur": [1, 4], "arm64": [1, 2, 6], "now": [1, 2, 3, 7, 8], "A": [1, 3, 6, 8], "maco": [1, 2, 6], "m1": 1, "includ": [1, 2, 3, 6, 8], "entri": 1, "sinc": [1, 4], "can": [1, 2, 3, 4, 5, 6, 7, 8], "cdecl": [1, 3, 6], "stdcall": [1, 3, 6, 7], "64": [1, 3, 5, 6, 8], "lp64d": [1, 6], "lp64": [1, 6, 8], "untest": [1, 6], "expos": [1, 8], "set": [1, 2, 4], "usag": [1, 4], "synchron": [1, 3, 5], "asynchron": [1, 5], "transpar": [1, 8], "between": [1, 3], "buffer": [1, 8], "tent": 1, "excess": 1, "align": [1, 8], "x86": [1, 3, 6, 7], "potenti": [1, 8], "problem": 1, "big": [1, 3, 5, 8], "int64_t": [1, 7, 8], "uint64_t": [1, 8], "layout": 1, "push": [1, 8], "pop": 1, "issu": [1, 3], "incomplet": 1, "buggi": 1, "hfa": [1, 2], "caus": [1, 3], "miss": [1, 2], "map_stack": 1, "flag": [1, 8], "non": [1, 3, 8], "sens": 1, "intern": [1, 8], "fals": [1, 8], "normal": [1, 5, 8], "make": [1, 2, 3], "sure": [1, 2], "we": [1, 2, 8], "have": [1, 2, 3, 7, 8], "redzon": 1, "architectur": [1, 2, 3, 4, 6, 8], "slower": 1, "alloc": [1, 5, 8], "object": [1, 2, 3, 5, 8], "repositori": 2, "luigi": [2, 4], "monorepo": 2, "contain": [2, 8], "multipl": [1, 2], "project": 2, "idea": 2, "github": [2, 4], "com": [2, 4], "koromix": [2, 4], "provid": [2, 3, 8], "packag": [1, 2, 6], "npm": [2, 6, 7], "archiv": 2, "so": [2, 3, 7, 8], "most": [2, 3, 8], "case": [2, 3, 8], "should": [1, 2, 8], "If": [1, 2, 3, 8], "you": [1, 2, 3, 4, 6, 7, 8], "want": [2, 7, 8], "hack": 2, "specif": [1, 2, 5, 8], "instruct": [2, 3], "start": [2, 3, 4], "clone": 2, "git": 2, "As": 2, "said": 2, "monorepositori": 2, "conta": 2, "henc": 2, "depend": [2, 3, 8], "met": 2, "desktop": 2, "develop": 2, "workload": 2, "visual": 2, "studio": 2, "2022": 2, "2019": 2, "tool": 2, "option": [2, 3, 4, 8], "compon": 2, "meta": 2, "12": [2, 6], "later": [2, 3, 4, 6], "done": [2, 3, 8], "benchmark": [2, 4], "directori": [2, 8], "what": 2, "gcc": 2, "g": [2, 3, 8], "3": [2, 4, 6, 8], "newer": [1, 2, 3, 6], "gnu": [2, 4], "81": 2, "emul": 2, "acceler": 2, "qemu": 2, "need": [1, 2, 3, 8], "even": 2, "gui": 2, "ubuntu": 2, "directli": [1, 2, 3, 5, 8], "licens": 2, "reason": [2, 8], "thei": [1, 2, 3, 8], "avail": [2, 4, 5], "file": [1, 2, 3, 8], "For": [1, 2, 3, 5, 6, 8], "exampl": [2, 4, 8], "wget": 2, "o": [2, 8], "qemu_debian_arm64": 2, "tar": 2, "zst": 2, "zstd": 2, "d": [2, 3, 8], "xv": 2, "sha256sum": 2, "ignor": [2, 3, 8], "registri": 2, "txt": 2, "disk": 2, "content": [2, 8], "mai": [1, 2, 3], "each": [2, 3, 8], "checksum": 2, "been": [1, 2, 3], "least": [2, 5], "And": [2, 7, 8], "sever": [2, 3], "help": 2, "patient": 2, "ccach": 2, "subsequ": [2, 3, 5], "step": 2, "more": [1, 2, 3, 4, 5, 6, 8], "toler": 2, "By": [2, 3, 8], "stop": 2, "But": [2, 3, 8], "ahead": 2, "shut": 2, "down": 2, "again": [2, 8], "also": [2, 3, 8], "subset": 2, "cycl": 2, "debian_x64": 2, "debian_i386": 2, "separ": 2, "shutdown": 2, "final": [2, 8], "join": 2, "ssh": 2, "shortcut": [2, 3], "some": [1, 2, 3, 8], "debug": 2, "manual": [2, 3], "procedur": [2, 3], "vnc": 2, "server": 2, "local": [2, 7], "access": [2, 3], "displai": 2, "krdc": 2, "viewer": 2, "info": 2, "port": 2, "plan": 2, "necessarili": 2, "pass": [1, 2, 3, 8], "avoid": [2, 3, 8], "properti": 2, "helper": 2, "autom": 2, "aarch64": [2, 6], "how": [2, 3, 4, 8], "thank": [2, 8], "appl": 2, "creat": [2, 3, 8], "real": 2, "world": [2, 3, 7, 8], "librari": [2, 3, 7, 8], "raylib": 2, "sqlite": [2, 3], "libsodium": 2, "illustr": [1, 2, 3, 7, 8], "parser": [1, 2, 3], "wai": [1, 2, 3, 7, 8], "encod": [2, 8], "decod": 2, "byte": [2, 5, 8], "union": 2, "powerpc": 2, "power9": 2, "assembl": [2, 5], "unwind": 2, "cfi": 2, "direct": [2, 8], "better": 2, "experi": 2, "program": [2, 3, 4], "It": [2, 3, 7, 8], "addon": 2, "interact": 2, "person": 2, "goe": 2, "rather": 2, "like": [1, 2, 7, 8], "care": [2, 3, 8], "templat": 2, "mainli": 2, "littl": 2, "orient": [2, 8], "i": [2, 8], "strongli": 2, "tag": 2, "over": 2, "inherit": 2, "virtual": 2, "method": 2, "To": 3, "declar": [3, 7, 8], "share": [3, 7, 8], "filenam": [3, 8], "const": [1, 3, 7, 8], "requir": [3, 4, 7, 8], "lib": [1, 3, 7, 8], "path": [3, 8], "extens": 3, "dll": [3, 7, 8], "dylib": 3, "etc": 3, "from": [3, 4, 6, 8], "two": [1, 3, 5, 8], "inspir": 3, "specifi": [3, 8], "its": [3, 8], "mangl": 3, "ellipsi": 3, "last": [3, 8], "printf": [3, 7], "func": [1, 3, 7, 8], "int": [1, 3, 7, 8], "atoi": 3, "tri": 3, "convent": [6, 7], "see": [3, 4, 8], "section": [3, 8], "inform": [1, 3, 4, 8], "subject": 3, "shown": [1, 3, 8], "fmt": 3, "onli": [1, 3, 6, 8], "per": 3, "process": 3, "32": 3, "bit": [3, 8], "form": 3, "descript": [3, 5], "__stdcall": [3, 8], "within": 3, "win32": [3, 7, 8], "fastcal": [3, 6], "__fastcal": 3, "rare": [3, 8], "ecx": 3, "edx": 3, "thiscal": [3, 6], "__thiscal": 3, "safe": 3, "simpli": [3, 8], "find": [3, 4, 7, 8], "show": [3, 7, 8], "user32": [3, 7], "equival": [1, 3, 8], "messageboxa_1": 3, "messageboxa": [3, 7], "uint": [3, 7, 8], "messageboxa_2": 3, "hwnd": 3, "text": 3, "caption": 3, "err": 3, "re": 3, "libc": [3, 7], "1257": 3, "log": [1, 3, 5, 8], "result": [3, 7, 8], "hello": [1, 3, 7, 8], "print": [3, 7, 8], "worker": 3, "your": [1, 3, 4], "respons": 3, "deal": [3, 8], "data": [3, 4], "multi": 3, "easili": 3, "style": [3, 4], "promis": 3, "util": [3, 4], "promisifi": 3, "cannot": [3, 5, 8], "must": [1, 3, 8], "addit": [1, 3, 8], "expect": [3, 6, 8], "5": [3, 8], "doubl": [3, 6, 8], "THE": 3, "end": 3, "On": 3, "forward": [3, 6], "howev": [3, 5, 8], "simplic": 3, "semant": [3, 8], "marshal": 3, "out": [3, 8], "e": [3, 8], "timev": [3, 7], "inout": 3, "dual": 3, "same": [1, 3, 5, 8], "msdn": 3, "qualifi": 3, "_out_": [1, 3, 7, 8], "_inout_": [3, 8], "posix": 3, "gettimeofdai": [3, 7], "tv_sec": [3, 7], "tv_usec": [3, 7], "timezon": [3, 7], "tz_minuteswest": [3, 7], "tz_dsttime": [3, 7], "tv": [3, 7], "tz": [3, 7], "let": [1, 3, 5, 7, 8], "databas": [1, 3], "sqlite3_db": [], "copi": [3, 8], "after": [1, 3, 8], "sqlite3_open_v2": [1, 3], "sqlite3_close_v2": [1, 3], "sqlite_open_readwrit": [1, 3], "0x2": [1, 3], "sqlite_open_cr": [1, 3], "0x4": [1, 3, 7], "db": [1, 3], "0": [3, 6, 8], "throw": [1, 3, 8], "while": [3, 8], "doe": [3, 5, 8], "know": 3, "someth": [3, 8], "freed": [3, 5], "matter": 3, "explicitli": [3, 8], "fclose": [1, 3, 8], "them": [1, 3, 8], "implicitli": 3, "lose": 3, "origin": 3, "dispos": [1, 3, 4], "deriv": 3, "anoth": [3, 7, 8], "differ": [1, 3, 6, 8], "being": 3, "anymor": 3, "omit": [3, 8], "anonym": [3, 8], "free": [3, 4, 8], "ptr": [1, 3, 8], "under": [3, 4], "hood": 3, "anonheapstr": 3, "namedheapstr": 3, "heapstr": 3, "thing": 3, "usabl": [1, 3, 8], "explicitfre": 3, "heapstr16": 3, "strdup": 3, "asprintf": [], "either": [3, 4, 8], "Be": 3, "crt": 3, "msvcrt": 3, "could": [3, 8], "malloc": [3, 8], "undefin": [1, 3, 8], "behavior": [1, 3, 8], "With": 3, "noth": 3, "examplecallback": 3, "sum": [3, 8], "adddoublefloat": 3, "f": [3, 8], "1": [3, 5, 6, 7, 8], "x": [3, 6, 8], "defin": [1, 3, 8], "obscur": [1, 3, 8], "underli": [1, 3, 8], "callit": [1, 3], "callbacktyp": [1, 3], "becom": [1, 3], "predefin": 3, "trampolin": 3, "gener": [3, 4, 8], "runtim": 3, "harden": 3, "w": 3, "migit": 3, "pax": 3, "mprotect": 3, "impos": 3, "durat": 3, "distinguish": [3, 8], "invalid": 3, "though": 3, "thrown": [1, 3], "guarante": 3, "don": 3, "special": 3, "unregist": 3, "exist": 3, "qsort": 3, "progress": 3, "sqlite3_exec": 3, "part": [3, 8], "h": [1, 3, 8], "transfertoj": [1, 3], "ag": [1, 3], "cb": [1, 3], "buf": [1, 3], "snprintf": [1, 3], "sizeof": [1, 3, 8], "fake": 3, "transfercallback": [1, 3], "ret": [1, 3, 7], "niel": [1, 3], "27": [1, 3], "42": [1, 3, 8], "handler": 3, "event": 3, "fopencooki": 3, "funopen": 3, "releas": 3, "slot": 3, "16": [3, 6, 7, 8], "failur": [3, 8], "registr": 3, "delai": 3, "g_cb1": 3, "g_cb2": 3, "registerfunct": 3, "cb1": 3, "cb2": 3, "sayit": 3, "getcallback": 3, "printcallback": 3, "kyoto": 3, "receiv": 3, "yourself": [3, 8], "try": [3, 8], "catch": 3, "precis": [3, 6], "intepret": 3, "lead": 3, "mess": [3, 8], "ve": 3, "warn": 3, "fast": 4, "easi": 4, "low": 4, "aggreg": 4, "both": [4, 8], "well": 4, "popular": 4, "os": [4, 6, 8], "combin": [4, 6], "recent": [4, 6], "page": [4, 5, 8], "sourc": [4, 6], "subdirectori": 4, "introspect": [], "gotcha": 4, "thread": 4, "safeti": 4, "work": [1, 4], "x86_64": [4, 6], "contribut": 4, "request": 4, "todo": 4, "list": [1, 4, 8], "changelog": 4, "softwar": 4, "redistribut": 4, "modifi": [4, 8], "term": 4, "affero": 4, "public": 4, "publish": 4, "foundat": 4, "www": 4, "org": 4, "prealloc": 5, "block": 5, "One": 5, "construct": 5, "assign": [5, 8], "regist": [1, 5, 8], "mib": 5, "unless": 5, "veri": 5, "extra": 5, "dure": 5, "engin": 5, "might": 5, "config": 5, "obj": 5, "appli": [5, 8], "true": [5, 8], "unus": 5, "resid": 5, "still": [1, 5], "finish": 5, "resident_async_pool": 5, "left": 5, "There": 5, "sync_stack_s": 5, "sync_heap_s": 5, "async_stack_s": 5, "256": 5, "kib": 5, "async_heap_s": 5, "512": 5, "pool": 5, "ongo": 5, "22": 6, "nvm": 6, "distribut": 6, "moment": 6, "isa": 6, "freebsd": 6, "ia32": 6, "ye": 6, "amd64": 6, "le": [6, 8], "probabl": [3, 6], "fulli": 6, "green": 6, "check": 6, "mark": 6, "mean": [6, 8], "ms": 6, "hard": 6, "vfp": 6, "coprocessor": 6, "softfp": 6, "soft": 6, "theori": 6, "lp64f": 6, "prototyp": [1, 7], "languag": 7, "syntax": [1, 7], "localtime_r": 7, "current": [7, 8], "time_t": 7, "tm": 7, "tm_sec": 7, "tm_min": 7, "tm_hour": 7, "tm_mdai": 7, "tm_mon": 7, "tm_year": 7, "tm_wdai": 7, "tm_ydai": 7, "tm_isdst": 7, "format": 7, "variad": 7, "02d": 7, "target": 7, "messagebox": 7, "user": [7, 8], "utf": [7, 8], "constant": 7, "mb_ok": 7, "0x0": 7, "mb_yesno": 7, "mb_iconquest": 7, "0x20": 7, "mb_iconinform": 7, "0x40": 7, "idok": 7, "idy": 7, "idno": 7, "messageboxw": 7, "box": 7, "allow": 8, "variat": 8, "enforc": 8, "signed": 8, "valid": 8, "int8": 8, "int8_t": 8, "uint8": 8, "uint8_t": 8, "uchar": 8, "int16": 8, "int16_t": 8, "uint16": 8, "uint16_t": 8, "short": 8, "int32": 8, "int32_t": 8, "uint32": 8, "uint32_t": [1, 8], "int64": 8, "uint64": 8, "longlong": 8, "ulonglong": 8, "float32": 8, "float64": 8, "accept": 8, "bigint": 8, "exce": 8, "rang": 8, "revers": 8, "boolean": 8, "bool": 8, "usual": 8, "ulong": 8, "intptr": 8, "width": 8, "uintptr": 8, "line": 8, "struct1": 8, "dummi": [1, 8], "struct2": 8, "vice": 8, "versa": 8, "unlik": 8, "typedef": 8, "b": 8, "d1": 8, "d2": 8, "rule": 8, "regard": 8, "pad": 8, "latter": 8, "function1": 8, "function2": 8, "differenti": 8, "purpos": 8, "import": 8, "fall": 8, "expens": 8, "stabil": 8, "dynam": 8, "termin": 8, "sentinel": 8, "length": 8, "lot": 8, "getcursorpo": 8, "retriev": 8, "cursor": 8, "posit": 8, "kernel32": 8, "y": 8, "po": 8, "kind": 8, "pair": 8, "dedic": 8, "delet": 8, "obviou": 8, "found": 8, "stdio": 8, "fopen": [1, 8], "manipul": 8, "fread": 8, "ftell": 8, "manag": [1, 8], "look": 8, "concatnewout": 8, "describ": 8, "builder": 8, "concaten": 8, "fizzbuzz": 8, "hidden": 8, "behind": 8, "destroi": 8, "concatnew": 8, "concatfre": 8, "fpic": 8, "wall": 8, "o2": 8, "stdlib": 8, "stdbool": 8, "errno": 8, "fragment": 8, "next": 8, "size_t": 8, "len": 8, "concat": 8, "total": 8, "fprintf": 8, "stderr": 8, "strerror": 8, "concatappend": 8, "frag": 8, "strlen": 8, "memcpi": 8, "concatbuild": 8, "r": 8, "stupid": 8, "30": 8, "buzz": 8, "fizz": 8, "infer": 8, "itself": 8, "translat": 8, "proper": 8, "notion": 8, "fat": 8, "calcul": 8, "stdint": 8, "computetotallength": 8, "just": 8, "findfirstfilew": 8, "findnextfilew": 8, "filetim": 8, "dwlowdatetim": 8, "dwhighdatetim": 8, "win32_find_data": 8, "dwfileattribut": 8, "ftcreationtim": 8, "ftlastaccesstim": 8, "ftlastwritetim": 8, "nfilesizehigh": 8, "nfilesizelow": 8, "dwreserved0": 8, "dwreserved1": 8, "cfilenam": 8, "260": 8, "calternatefilenam": 8, "dwfiletyp": 8, "obsolet": 8, "dwcreatortyp": 8, "wfinderflag": 8, "ushort": 8, "findfirstfil": 8, "findnextfil": 8, "findclos": 8, "getlasterror": 8, "dirnam": 8, "error_file_not_found": 8, "18": 8, "error_no_more_fil": 8, "among": 8, "variabl": 8, "invol": 8, "list1": 8, "list2": 8, "singl": [1, 8], "element": [1, 8], "store": 8, "addint": 8, "dest": 8, "36": 8, "degener": 8, "emb": 8, "correct": [3, 8], "uint8arrai": 8, "those": 8, "exactli": 8, "foo1": 8, "foo": 8, "a16": 8, "foo2": 8, "hypothet": 8, "returnfoo1": 8, "returnfoo": 8, "p": 8, "returnfoo2": 8, "int16arrai": 8, "fill": 8, "truncat": 8, "alwai": 8, "nul": 8, "ask": 8, "explor": 8, "alignof": 8, "about": 8, "caller": [], "yarn": 1, "broken": 1, "pars": 1, "incorrect": 1, "stream": [], "fp": 1, "touch": [], "wb": 1, "would": 1, "initi": 1, "structtyp": 1, "sqlite3": [1, 3], "histori": 4, "migrat": [3, 4, 8], "guid": [3, 4, 8], "given": 1, "transient": 1, "magic": 1, "instrospect": [], "consult": [1, 3, 8], "complex": 1, "outsid": 1, "minor": 1, "alia": [1, 8], "resolv": [1, 8], "correctli": 1, "break": 1, "complet": 8, "read": 8, "handl": 1, "deprec": [1, 8], "replac": 1, "former": 1, "eventu": [1, 8], "remov": [1, 8], "overrid": 8, "pack": 8, "packedstruct": 8, "bigstruct": 8, "introduc": 8, "behav": 8, "reproduc": 8, "gethandleinform": 8, "closehandl": 8}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"benchmark": 0, "overview": [0, 4], "linux": [0, 7], "x86_64": 0, "rand": 0, "result": 0, "atoi": 0, "raylib": 0, "window": [0, 2, 7], "run": [0, 2], "changelog": 1, "koffi": [1, 4, 7], "1": [1, 4], "3": 1, "9": 1, "8": 1, "7": 1, "6": 1, "5": 1, "4": 1, "2": [1, 4], "0": [1, 4], "contribut": 2, "bug": 2, "featur": 2, "request": 2, "build": 2, "from": 2, "sourc": 2, "other": 2, "platform": [2, 6], "test": 2, "todo": 2, "list": 2, "code": 2, "style": 2, "function": [3, 8], "call": 3, "definit": [3, 8], "classic": 3, "syntax": 3, "c": [3, 8], "like": 3, "prototyp": 3, "synchron": [], "asynchron": 3, "variad": 3, "js": [3, 6], "convers": 3, "gotcha": 3, "output": 3, "paramet": 3, "struct": [3, 8], "exampl": [3, 7], "opaqu": [1, 3, 8], "handl": [3, 8], "heap": 3, "alloc": 3, "valu": 3, "javascript": 3, "callback": [1, 3], "transient": 3, "regist": 3, "except": 3, "thread": 3, "safeti": 3, "tabl": 4, "content": 4, "licens": 4, "memori": 5, "usag": 5, "how": 5, "work": 5, "default": 5, "set": 5, "requir": 6, "node": 6, "support": 6, "quick": 7, "start": 7, "instal": 7, "small": 7, "data": 8, "type": [1, 3, 8], "primit": 8, "pointer": 8, "arrai": 8, "fix": 8, "size": 8, "string": 8, "introspect": [1, 8], "convent": 3, "histori": 1, "12": 1, "11": 1, "10": 1, "migrat": 1, "guid": 1, "x": 1, "alias": 8, "dispos": 8, "util": 8, "public": [], "name": 8}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 56}})
@@ -174,8 +174,8 @@
174
174
 
175
175
  </div>
176
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.0.1-brightgreen" alt="NPM"/></a>
177
178
  <a href="https://github.com/Koromix/luigi/tree/master/koffi"><img src="https://img.shields.io/badge/GitHub-Koffi-ff6600" alt="GitHub"/></a>
178
- <a href="https://github.com/Koromix/luigi/tree/master/koffi"><img src="https://img.shields.io/badge/NPM-2.0.0-brightgreen" alt="NPM"/></a>
179
179
  </div>
180
180
  </div>
181
181
 
@@ -174,8 +174,8 @@
174
174
 
175
175
  </div>
176
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.0.1-brightgreen" alt="NPM"/></a>
177
178
  <a href="https://github.com/Koromix/luigi/tree/master/koffi"><img src="https://img.shields.io/badge/GitHub-Koffi-ff6600" alt="GitHub"/></a>
178
- <a href="https://github.com/Koromix/luigi/tree/master/koffi"><img src="https://img.shields.io/badge/NPM-2.0.0-brightgreen" alt="NPM"/></a>
179
179
  </div>
180
180
  </div>
181
181
 
@@ -223,7 +223,7 @@
223
223
  </tr>
224
224
  </thead>
225
225
  <tbody>
226
- <tr class="row-even"><td><p>Null</p></td>
226
+ <tr class="row-even"><td><p>Undefined</p></td>
227
227
  <td><p>void</p></td>
228
228
  <td><p>0</p></td>
229
229
  <td><p></p></td>
@@ -510,6 +510,8 @@
510
510
  </section>
511
511
  <section id="struct-types">
512
512
  <h2>Struct types<a class="headerlink" href="#struct-types" title="Permalink to this heading">#</a></h2>
513
+ <section id="struct-definition">
514
+ <h3>Struct definition<a class="headerlink" href="#struct-definition" title="Permalink to this heading">#</a></h3>
513
515
  <p>Koffi converts JS objects to C structs, and vice-versa.</p>
514
516
  <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>
515
517
  <p>The following example illustrates how to declare the same struct in C and in JS with Koffi:</p>
@@ -542,51 +544,38 @@
542
544
  <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>
543
545
  </pre></div>
544
546
  </div>
545
- </section>
546
- <section id="pointer-types">
547
- <h2>Pointer types<a class="headerlink" href="#pointer-types" title="Permalink to this heading">#</a></h2>
548
- <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>
547
+ <p>Koffi automatically follows the platform C ABI regarding alignment and padding. However, you can override these rules if needed with:</p>
549
548
  <ul class="simple">
550
- <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>
551
- <li><p><strong>Opaque handles</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 a handle. This is usually done for ABI-stability reason, and to prevent library users from messing directly with library internals.</p></li>
552
- <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>
553
- <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>
549
+ <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>
550
+ <li><p>Change alignment of a specific member as shown below</p></li>
554
551
  </ul>
555
- <section id="struct-pointers">
556
- <h3>Struct pointers<a class="headerlink" href="#struct-pointers" title="Permalink to this heading">#</a></h3>
557
- <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>
558
- <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>
559
- <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>
560
- <span class="linenos"> 3</span>
561
- <span class="linenos"> 4</span><span class="c1">// Type declarations</span>
562
- <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>
563
- <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>
564
- <span class="linenos"> 7</span> <span class="nx">y</span><span class="o">:</span> <span class="s1">&#39;long&#39;</span>
565
- <span class="linenos"> 8</span><span class="p">});</span>
566
- <span class="linenos"> 9</span>
567
- <span class="linenos">10</span><span class="c1">// Functions declarations</span>
568
- <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>
569
- <span class="linenos">12</span>
570
- <span class="linenos">13</span><span class="c1">// Get and show cursor position</span>
571
- <span class="linenos">14</span><span class="kd">let</span> <span class="nx">pos</span> <span class="o">=</span> <span class="p">{};</span>
572
- <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>
573
- <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>
574
- <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>
552
+ <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>
553
+ <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>
554
+ <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>
555
+ <span class="linenos"> 4</span> <span class="nx">b</span><span class="o">:</span> <span class="s1">&#39;int16_t&#39;</span>
556
+ <span class="linenos"> 5</span><span class="p">});</span>
557
+ <span class="linenos"> 6</span>
558
+ <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>
559
+ <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>
560
+ <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>
561
+ <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>
562
+ <span class="linenos">11</span><span class="p">})</span>
575
563
  </pre></div>
576
564
  </div>
577
565
  </section>
578
- <section id="opaque-handles">
579
- <h3>Opaque handles<a class="headerlink" href="#opaque-handles" title="Permalink to this heading">#</a></h3>
580
- <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 handle 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>
581
- <p>In Koffi, you can manage this with opaque handles. Declare the handle type with <code class="docutils literal notranslate"><span class="pre">koffi.handle(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>
566
+ <section id="opaque-types">
567
+ <h3>Opaque types<a class="headerlink" href="#opaque-types" title="Permalink to this heading">#</a></h3>
568
+ <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>
569
+ <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>
582
570
  <div class="admonition note">
583
571
  <p class="admonition-title">Note</p>
584
- <p>Opaque handles <strong>have changed in version 2.0</strong>.</p>
572
+ <p>Opaque types <strong>have changed in version 2.0, and again in version 2.1</strong>.</p>
585
573
  <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>
586
574
  <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>
575
+ <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>
587
576
  <p>Consult the <a class="reference internal" href="changes"><span class="doc std std-doc">migration guide</span></a> for more information.</p>
588
577
  </div>
589
- <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 handle, 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>
578
+ <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>
590
579
  <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>
591
580
  <span class="linenos"> 2</span>
592
581
  <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>
@@ -708,7 +697,7 @@
708
697
  <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>
709
698
  <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>
710
699
  <span class="linenos"> 3</span>
711
- <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">handle</span><span class="p">(</span><span class="s1">&#39;Concat&#39;</span><span class="p">);</span>
700
+ <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>
712
701
  <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>
713
702
  <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>
714
703
  <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>
@@ -758,6 +747,50 @@
758
747
  </pre></div>
759
748
  </div>
760
749
  </section>
750
+ </section>
751
+ <section id="pointer-types">
752
+ <h2>Pointer types<a class="headerlink" href="#pointer-types" title="Permalink to this heading">#</a></h2>
753
+ <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>
754
+ <ul class="simple">
755
+ <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>
756
+ <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>
757
+ <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>
758
+ <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>
759
+ </ul>
760
+ <section id="struct-pointers">
761
+ <h3>Struct pointers<a class="headerlink" href="#struct-pointers" title="Permalink to this heading">#</a></h3>
762
+ <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>
763
+ <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>
764
+ <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>
765
+ <span class="linenos"> 3</span>
766
+ <span class="linenos"> 4</span><span class="c1">// Type declarations</span>
767
+ <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>
768
+ <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>
769
+ <span class="linenos"> 7</span> <span class="nx">y</span><span class="o">:</span> <span class="s1">&#39;long&#39;</span>
770
+ <span class="linenos"> 8</span><span class="p">});</span>
771
+ <span class="linenos"> 9</span>
772
+ <span class="linenos">10</span><span class="c1">// Functions declarations</span>
773
+ <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>
774
+ <span class="linenos">12</span>
775
+ <span class="linenos">13</span><span class="c1">// Get and show cursor position</span>
776
+ <span class="linenos">14</span><span class="kd">let</span> <span class="nx">pos</span> <span class="o">=</span> <span class="p">{};</span>
777
+ <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>
778
+ <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>
779
+ <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>
780
+ </pre></div>
781
+ </div>
782
+ </section>
783
+ <section id="named-pointer-types">
784
+ <h3>Named pointer types<a class="headerlink" href="#named-pointer-types" title="Permalink to this heading">#</a></h3>
785
+ <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>
786
+ <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>
787
+ <span class="linenos">2</span>
788
+ <span class="linenos">3</span><span class="c1">// And now you get to use it this way:</span>
789
+ <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>
790
+ <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>
791
+ </pre></div>
792
+ </div>
793
+ </section>
761
794
  <section id="array-pointers">
762
795
  <h3>Array pointers<a class="headerlink" href="#array-pointers" title="Permalink to this heading">#</a></h3>
763
796
  <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>
@@ -798,7 +831,7 @@
798
831
  <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>
799
832
  <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>
800
833
  <span class="linenos"> 3</span>
801
- <span class="linenos"> 4</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">handle</span><span class="p">());</span>
834
+ <span class="linenos"> 4</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
835
  <span class="linenos"> 5</span><span class="kd">const</span> <span class="nx">FILETIME</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;FILETIME&#39;</span><span class="p">,</span> <span class="p">{</span>
803
836
  <span class="linenos"> 6</span> <span class="nx">dwLowDateTime</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span><span class="p">,</span>
804
837
  <span class="linenos"> 7</span> <span class="nx">dwHighDateTime</span><span class="o">:</span> <span class="s1">&#39;uint&#39;</span>
@@ -1021,10 +1054,14 @@
1021
1054
  <ul>
1022
1055
  <li><a class="reference internal" href="#">Data types</a><ul>
1023
1056
  <li><a class="reference internal" href="#primitive-types">Primitive types</a></li>
1024
- <li><a class="reference internal" href="#struct-types">Struct types</a></li>
1057
+ <li><a class="reference internal" href="#struct-types">Struct types</a><ul>
1058
+ <li><a class="reference internal" href="#struct-definition">Struct definition</a></li>
1059
+ <li><a class="reference internal" href="#opaque-types">Opaque types</a></li>
1060
+ </ul>
1061
+ </li>
1025
1062
  <li><a class="reference internal" href="#pointer-types">Pointer types</a><ul>
1026
1063
  <li><a class="reference internal" href="#struct-pointers">Struct pointers</a></li>
1027
- <li><a class="reference internal" href="#opaque-handles">Opaque handles</a></li>
1064
+ <li><a class="reference internal" href="#named-pointer-types">Named pointer types</a></li>
1028
1065
  <li><a class="reference internal" href="#array-pointers">Array pointers</a></li>
1029
1066
  <li><a class="reference internal" href="#pointers-to-primitive-types">Pointers to primitive types</a></li>
1030
1067
  </ul>
package/doc/functions.md CHANGED
@@ -114,7 +114,7 @@ By default, Koffi will only forward arguments from Javascript to C. However, man
114
114
  For simplicity, and because Javascript only has value semantics for primitive types, Koffi can marshal out (or in/out) two types of parameters:
115
115
 
116
116
  - [Structs](types.md#struct-types) (to/from JS objects)
117
- - [Opaque handles](types.md#opaque-handles)
117
+ - [Opaque types](types.md#opaque-types)
118
118
 
119
119
  In order to change an argument from input-only to output or input/output, use the following functions:
120
120
 
@@ -152,7 +152,7 @@ gettimeofday(tv, null);
152
152
  console.log(tv);
153
153
  ```
154
154
 
155
- #### Opaque handle example
155
+ #### Opaque type example
156
156
 
157
157
  This example opens an in-memory SQLite database, and uses the node-ffi-style function declaration syntax.
158
158
 
@@ -160,7 +160,7 @@ This example opens an in-memory SQLite database, and uses the node-ffi-style fun
160
160
  const koffi = require('koffi');
161
161
  const lib = koffi.load('sqlite3.so');
162
162
 
163
- const sqlite3 = koffi.handle('sqlite3');
163
+ const sqlite3 = koffi.opaque('sqlite3');
164
164
 
165
165
  // Use koffi.out() on a double pointer to copy out (from C to JS) after the call
166
166
  const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['str', koffi.out(koffi.pointer(sqlite3, 2)), 'int', 'str']);
@@ -181,7 +181,7 @@ sqlite3_close_v2(db);
181
181
 
182
182
  Some C functions return heap-allocated values directly or through output parameters. While Koffi automatically converts values from C to JS (to a string or an object), it does not know when something needs to be freed, or how.
183
183
 
184
- For opaque handles, such as FILE, this does not matter because you will explicitly call `fclose()` on them. But some values (such as strings) get implicitly converted by Koffi, and you lose access to the original pointer. This creates a leak if the string is heap-allocated.
184
+ For opaque types, such as FILE, this does not matter because you will explicitly call `fclose()` on them. But some values (such as strings) get implicitly converted by Koffi, and you lose access to the original pointer. This creates a leak if the string is heap-allocated.
185
185
 
186
186
  To avoid this, you can instruct Koffi to call a function on the original pointer once the conversion is done, by creating a **disposable type** with `koffi.dispose(name, type, func)`. This creates a type derived from another type, the only difference being that *func* gets called with the original pointer once the value has been converted and is not needed anymore.
187
187
 
package/doc/types.md CHANGED
@@ -69,6 +69,8 @@ let struct2 = koffi.struct({ dummy: koffi.types.long });
69
69
 
70
70
  ## Struct types
71
71
 
72
+ ### Struct definition
73
+
72
74
  Koffi converts JS objects to C structs, and vice-versa.
73
75
 
74
76
  Unlike function declarations, as of now there is only one way to create a struct type, with the `koffi.struct()` 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.
@@ -109,56 +111,44 @@ const Function1 = lib.func('A Function(A value)');
109
111
  const Function2 = lib.func('Function', A, [A]);
110
112
  ```
111
113
 
112
- ## Pointer types
114
+ Koffi automatically follows the platform C ABI regarding alignment and padding. However, you can override these rules if needed with:
113
115
 
114
- 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:
115
-
116
- - **Struct pointers**: 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).
117
- - **Opaque handles**: the library does not expose the contents of the structs, and only provides you with a pointer to it (e.g. `FILE *`). Only the functions provided by the library can do something with this pointer, in Koffi we call this a handle. This is usually done for ABI-stability reason, and to prevent library users from messing directly with library internals.
118
- - **Arrays**: 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.
119
- - **Pointers to primitive types**: This is more rare, and generally used for output or input/output arguments. The Win32 API has a lot of these.
120
-
121
- ### Struct pointers
122
-
123
- The following Win32 example uses `GetCursorPos()` (with an output parameter) to retrieve and show the current cursor position.
116
+ - Pack all members without padding with `koffi.pack()` (instead of `koffi.struct()`)
117
+ - Change alignment of a specific member as shown below
124
118
 
125
119
  ```js
126
- const koffi = require('koffi');
127
- const lib = koffi.load('kernel32.dll');
128
-
129
- // Type declarations
130
- const POINT = koffi.struct('POINT', {
131
- x: 'long',
132
- y: 'long'
120
+ // This struct is 3 bytes long
121
+ const PackedStruct = koffi.pack('PackedStruct', {
122
+ a: 'int8_t',
123
+ b: 'int16_t'
133
124
  });
134
125
 
135
- // Functions declarations
136
- const GetCursorPos = lib.func('int __stdcall GetCursorPos(_Out_ POINT *pos)');
137
-
138
- // Get and show cursor position
139
- let pos = {};
140
- if (!GetCursorPos(pos))
141
- throw new Error('Failed to get cursor position');
142
- console.log(pos);
126
+ // This one is 18 bytes long, the second member has an alignment requirement of 16 bytes
127
+ const BigStruct = koffi.struct('BigStruct', {
128
+ a: 'int8_t',
129
+ b: [16, 'int16_t']
130
+ })
143
131
  ```
144
132
 
145
- ### Opaque handles
133
+ ### Opaque types
146
134
 
147
- 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 `FILE *` pointer. You can open and close files with `fopen()` and `fclose()`, and manipule the handle with other functions such as `fread()` or `ftell()`.
135
+ 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 `FILE *` pointer. You can open and close files with `fopen()` and `fclose()`, and manipule the opaque pointer with other functions such as `fread()` or `ftell()`.
148
136
 
149
- In Koffi, you can manage this with opaque handles. Declare the handle type with `koffi.handle(name)`, and use a pointer to this type either as a return type or some kind of [output parameter](functions.md#output-parameters) (with a double pointer).
137
+ In Koffi, you can manage this with opaque types. Declare the opaque type with `koffi.opaque(name)`, and use a pointer to this type either as a return type or some kind of [output parameter](functions.md#output-parameters) (with a double pointer).
150
138
 
151
139
  ```{note}
152
- Opaque handles **have changed in version 2.0**.
140
+ Opaque types **have changed in version 2.0, and again in version 2.1**.
153
141
 
154
142
  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.
155
143
 
156
144
  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 `ConcatNewOut` in the JS part), and is described in the section on [output parameters](functions.md#output-parameters).
157
145
 
146
+ In addition to this, you should use `koffi.opaque()` (introduced in Koffi 2.1) instead of `koffi.handle()` which is deprecated, and will be removed eventually in Koffi 3.0.
147
+
158
148
  Consult the [migration guide](changes.md) for more information.
159
149
  ```
160
150
 
161
- 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 handle, and is created and destroyed using a pair of C functions: `ConcatNew` (or `ConcatNewOut`) and `ConcatFree`.
151
+ 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: `ConcatNew` (or `ConcatNewOut`) and `ConcatFree`.
162
152
 
163
153
  ```c
164
154
  // Build with: clang -fPIC -o handles.so -shared handles.c -Wall -O2
@@ -283,7 +273,7 @@ const char *ConcatBuild(Concat *c)
283
273
  const koffi = require('koffi');
284
274
  const lib = koffi.load('./handles.so');
285
275
 
286
- const Concat = koffi.handle('Concat');
276
+ const Concat = koffi.opaque('Concat');
287
277
  const ConcatNewOut = lib.func('bool ConcatNewOut(_Out_ Concat **out)');
288
278
  const ConcatNew = lib.func('Concat *ConcatNew()');
289
279
  const ConcatFree = lib.func('void ConcatFree(Concat *c)');
@@ -332,6 +322,51 @@ try {
332
322
  }
333
323
  ```
334
324
 
325
+ ## Pointer types
326
+
327
+ 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:
328
+
329
+ - **Struct pointers**: 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).
330
+ - **Opaque pointers**: the library does not expose the contents of the structs, and only provides you with a pointer to it (e.g. `FILE *`). 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.
331
+ - **Arrays**: 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.
332
+ - **Pointers to primitive types**: This is more rare, and generally used for output or input/output arguments. The Win32 API has a lot of these.
333
+
334
+ ### Struct pointers
335
+
336
+ The following Win32 example uses `GetCursorPos()` (with an output parameter) to retrieve and show the current cursor position.
337
+
338
+ ```js
339
+ const koffi = require('koffi');
340
+ const lib = koffi.load('kernel32.dll');
341
+
342
+ // Type declarations
343
+ const POINT = koffi.struct('POINT', {
344
+ x: 'long',
345
+ y: 'long'
346
+ });
347
+
348
+ // Functions declarations
349
+ const GetCursorPos = lib.func('int __stdcall GetCursorPos(_Out_ POINT *pos)');
350
+
351
+ // Get and show cursor position
352
+ let pos = {};
353
+ if (!GetCursorPos(pos))
354
+ throw new Error('Failed to get cursor position');
355
+ console.log(pos);
356
+ ```
357
+
358
+ ### Named pointer types
359
+
360
+ 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 **named pointer type** to an opaque type, like so:
361
+
362
+ ```js
363
+ const HANDLE = koffi.pointer('HANDLE', koffi.opaque());
364
+
365
+ // And now you get to use it this way:
366
+ const GetHandleInformation = lib.func('bool __stdcall GetHandleInformation(HANDLE h, _Out_ uint32_t *flags)');
367
+ const CloseHandle = lib.func('bool __stdcall CloseHandle(HANDLE h)');
368
+ ```
369
+
335
370
  ### Array pointers
336
371
 
337
372
  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).
@@ -380,7 +415,7 @@ Here is an example based on the Win32 API, listing files in the current director
380
415
  const koffi = require('koffi');
381
416
  const lib = koffi.load('kernel32.dll');
382
417
 
383
- const HANDLE = koffi.pointer('HANDLE', koffi.handle());
418
+ const HANDLE = koffi.pointer('HANDLE', koffi.opaque());
384
419
  const FILETIME = koffi.struct('FILETIME', {
385
420
  dwLowDateTime: 'uint',
386
421
  dwHighDateTime: 'uint'