koffi 1.3.12 → 2.0.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 (89) hide show
  1. package/CMakeLists.txt +7 -2
  2. package/ChangeLog.md +42 -16
  3. package/README.md +6 -0
  4. package/build/qemu/2.0.0/koffi_darwin_arm64.tar.gz +0 -0
  5. package/build/qemu/2.0.0/koffi_darwin_x64.tar.gz +0 -0
  6. package/build/qemu/2.0.0/koffi_freebsd_arm64.tar.gz +0 -0
  7. package/build/qemu/2.0.0/koffi_freebsd_ia32.tar.gz +0 -0
  8. package/build/qemu/2.0.0/koffi_freebsd_x64.tar.gz +0 -0
  9. package/build/qemu/2.0.0/koffi_linux_arm32hf.tar.gz +0 -0
  10. package/build/qemu/2.0.0/koffi_linux_arm64.tar.gz +0 -0
  11. package/build/qemu/2.0.0/koffi_linux_ia32.tar.gz +0 -0
  12. package/build/qemu/2.0.0/koffi_linux_riscv64hf64.tar.gz +0 -0
  13. package/build/qemu/2.0.0/koffi_linux_x64.tar.gz +0 -0
  14. package/build/qemu/2.0.0/koffi_openbsd_ia32.tar.gz +0 -0
  15. package/build/qemu/2.0.0/koffi_openbsd_x64.tar.gz +0 -0
  16. package/build/qemu/2.0.0/koffi_win32_arm64.tar.gz +0 -0
  17. package/build/qemu/2.0.0/koffi_win32_ia32.tar.gz +0 -0
  18. package/build/qemu/2.0.0/koffi_win32_x64.tar.gz +0 -0
  19. package/doc/benchmarks.md +2 -2
  20. package/doc/changes.md +156 -1
  21. package/doc/contribute.md +0 -1
  22. package/doc/dist/doctrees/changes.doctree +0 -0
  23. package/doc/dist/doctrees/environment.pickle +0 -0
  24. package/doc/dist/doctrees/functions.doctree +0 -0
  25. package/doc/dist/doctrees/types.doctree +0 -0
  26. package/doc/dist/html/_sources/changes.md.txt +156 -1
  27. package/doc/dist/html/_sources/functions.md.txt +8 -4
  28. package/doc/dist/html/_sources/types.md.txt +9 -0
  29. package/doc/dist/html/benchmarks.html +1 -1
  30. package/doc/dist/html/changes.html +226 -14
  31. package/doc/dist/html/contribute.html +1 -1
  32. package/doc/dist/html/functions.html +15 -12
  33. package/doc/dist/html/genindex.html +1 -1
  34. package/doc/dist/html/index.html +6 -16
  35. package/doc/dist/html/memory.html +3 -3
  36. package/doc/dist/html/objects.inv +0 -0
  37. package/doc/dist/html/platforms.html +1 -1
  38. package/doc/dist/html/search.html +1 -1
  39. package/doc/dist/html/searchindex.js +1 -1
  40. package/doc/dist/html/start.html +1 -1
  41. package/doc/dist/html/types.html +11 -3
  42. package/doc/functions.md +137 -13
  43. package/doc/types.md +35 -10
  44. package/package.json +1 -1
  45. package/qemu/registry/machines.json +5 -5
  46. package/qemu/registry/sha256sum.txt +16 -16
  47. package/src/abi_arm32.cc +90 -18
  48. package/src/abi_arm32_fwd.S +121 -57
  49. package/src/abi_arm64.cc +90 -18
  50. package/src/abi_arm64_fwd.S +96 -0
  51. package/src/abi_arm64_fwd.asm +128 -0
  52. package/src/abi_riscv64.cc +88 -18
  53. package/src/abi_riscv64_fwd.S +96 -0
  54. package/src/abi_x64_sysv.cc +93 -21
  55. package/src/abi_x64_sysv_fwd.S +96 -0
  56. package/src/abi_x64_win.cc +88 -18
  57. package/src/abi_x64_win_fwd.asm +128 -0
  58. package/src/abi_x86.cc +93 -18
  59. package/src/abi_x86_fwd.S +96 -0
  60. package/src/abi_x86_fwd.asm +128 -0
  61. package/src/call.cc +97 -63
  62. package/src/call.hh +2 -1
  63. package/src/ffi.cc +452 -140
  64. package/src/ffi.hh +23 -9
  65. package/src/parser.cc +18 -41
  66. package/src/util.cc +117 -27
  67. package/src/util.hh +3 -2
  68. package/test/callbacks.js +54 -8
  69. package/test/misc.c +29 -14
  70. package/test/raylib.js +1 -1
  71. package/test/sqlite.js +24 -16
  72. package/test/sync.js +41 -31
  73. package/vendor/libcc/libcc.cc +18 -5
  74. package/vendor/libcc/libcc.hh +70 -23
  75. package/build/qemu/1.3.12/koffi_darwin_arm64.tar.gz +0 -0
  76. package/build/qemu/1.3.12/koffi_darwin_x64.tar.gz +0 -0
  77. package/build/qemu/1.3.12/koffi_freebsd_arm64.tar.gz +0 -0
  78. package/build/qemu/1.3.12/koffi_freebsd_ia32.tar.gz +0 -0
  79. package/build/qemu/1.3.12/koffi_freebsd_x64.tar.gz +0 -0
  80. package/build/qemu/1.3.12/koffi_linux_arm32hf.tar.gz +0 -0
  81. package/build/qemu/1.3.12/koffi_linux_arm64.tar.gz +0 -0
  82. package/build/qemu/1.3.12/koffi_linux_ia32.tar.gz +0 -0
  83. package/build/qemu/1.3.12/koffi_linux_riscv64hf64.tar.gz +0 -0
  84. package/build/qemu/1.3.12/koffi_linux_x64.tar.gz +0 -0
  85. package/build/qemu/1.3.12/koffi_openbsd_ia32.tar.gz +0 -0
  86. package/build/qemu/1.3.12/koffi_openbsd_x64.tar.gz +0 -0
  87. package/build/qemu/1.3.12/koffi_win32_arm64.tar.gz +0 -0
  88. package/build/qemu/1.3.12/koffi_win32_ia32.tar.gz +0 -0
  89. package/build/qemu/1.3.12/koffi_win32_x64.tar.gz +0 -0
package/CMakeLists.txt CHANGED
@@ -113,8 +113,13 @@ endif()
113
113
  if(NOT MSVC OR CMAKE_C_COMPILER_ID MATCHES "[Cc]lang")
114
114
  # Restore C/C++ compiler sanity
115
115
 
116
- target_compile_options(koffi PRIVATE -fno-exceptions -fno-strict-aliasing -fwrapv
117
- -fno-delete-null-pointer-checks)
116
+ if(NOT MSVC)
117
+ target_compile_options(koffi PRIVATE -fno-exceptions -fno-strict-aliasing -fwrapv
118
+ -fno-delete-null-pointer-checks)
119
+ else()
120
+ target_compile_options(koffi PRIVATE -fno-strict-aliasing /clang:-fwrapv
121
+ -fno-delete-null-pointer-checks)
122
+ endif()
118
123
 
119
124
  check_cxx_compiler_flag(-fno-finite-loops use_no_finite_loops)
120
125
  if(use_no_finite_loops)
package/ChangeLog.md CHANGED
@@ -1,18 +1,44 @@
1
1
  # Changelog
2
2
 
3
- ## Koffi 1.3.12
3
+ ## History
4
+
5
+ ### Koffi 2.0.0
6
+
7
+ **Major new features:**
8
+
9
+ - Add disposable types for automatic disposal of C values (such as heap-allocated strings)
10
+ - Add support for registered callbacks, that can be called after the initial FFI call
11
+ - Support named pointer types
12
+ - Support complex type specifications outside of prototype parser
13
+
14
+ **Minor new features:**
15
+
16
+ - Support type aliases with `koffi.alias()`
17
+ - Add `koffi.resolve()` to resolve type strings
18
+ - Expose all primitive type aliases in `koffi.types`
19
+ - Correctly pass exceptions thrown in JS callbacks
20
+
21
+ **Breaking API changes:**
22
+
23
+ - Change handling of callback types, which must be used through pointers
24
+ - Change handling of opaque handles, which must be used through pointers
25
+ - Support all types in `koffi.introspect(type)`
26
+
27
+ Consult the [migration guide](changes.md#migration-guide) for more information.
28
+
29
+ ### Koffi 1.3.12
4
30
 
5
31
  **Main fixes:**
6
32
 
7
33
  - Fix support for Yarn package manager
8
34
 
9
- ## Koffi 1.3.11
35
+ ### Koffi 1.3.11
10
36
 
11
37
  **Main fixes:**
12
38
 
13
39
  - Fix broken parsing of `void *` when used for first parameter
14
40
 
15
- ## Koffi 1.3.10
41
+ ### Koffi 1.3.10
16
42
 
17
43
  **Main fixes:**
18
44
 
@@ -24,13 +50,13 @@
24
50
 
25
51
  - Various documentation fixes and improvements
26
52
 
27
- ## Koffi 1.3.9
53
+ ### Koffi 1.3.9
28
54
 
29
55
  **Main fixes:**
30
56
 
31
57
  - Fix prebuild compatibility with Electron on Windows x64
32
58
 
33
- ## Koffi 1.3.8
59
+ ### Koffi 1.3.8
34
60
 
35
61
  **Main changes:**
36
62
 
@@ -41,7 +67,7 @@
41
67
 
42
68
  - Fix and harmonize a few error messages
43
69
 
44
- ## Koffi 1.3.7
70
+ ### Koffi 1.3.7
45
71
 
46
72
  **Main fixes:**
47
73
 
@@ -54,7 +80,7 @@
54
80
  - Add str/str16 type aliases for string/string16
55
81
  - Various documentation fixes and improvements
56
82
 
57
- ## Koffi 1.3.6
83
+ ### Koffi 1.3.6
58
84
 
59
85
  **Main fixes:**
60
86
 
@@ -66,7 +92,7 @@
66
92
  - Prebuild with Clang for Windows x64 and Linux x64 binaries
67
93
  - Various documentation improvements
68
94
 
69
- ## Koffi 1.3.5
95
+ ### Koffi 1.3.5
70
96
 
71
97
  **Main changes:**
72
98
 
@@ -78,13 +104,13 @@
78
104
  - Reduce default async memory stack and heap size
79
105
  - Various documentation improvements
80
106
 
81
- ## Koffi 1.3.4
107
+ ### Koffi 1.3.4
82
108
 
83
109
  **Main fixes:**
84
110
 
85
111
  - Fix possible OpenBSD i386 crash with `(void)` functions
86
112
 
87
- ## Koffi 1.3.3
113
+ ### Koffi 1.3.3
88
114
 
89
115
  **Main fixes:**
90
116
 
@@ -96,20 +122,20 @@
96
122
  - Disable unsafe compiler optimizations
97
123
  - Various documentation improvements
98
124
 
99
- ## Koffi 1.3.2
125
+ ### Koffi 1.3.2
100
126
 
101
127
  **Main fixes:**
102
128
 
103
129
  - Support compilation in C++14 mode (graceful degradation)
104
130
  - Support older toolchains on Linux (tested on Debian 9)
105
131
 
106
- ## Koffi 1.3.1
132
+ ### Koffi 1.3.1
107
133
 
108
134
  **Main fixes:**
109
135
 
110
136
  - The prebuilt binary is tested when Koffi is installed, and a rebuild happens if it fails to load
111
137
 
112
- ## Koffi 1.3.0
138
+ ### Koffi 1.3.0
113
139
 
114
140
  **Major changes:**
115
141
 
@@ -125,19 +151,19 @@
125
151
  - Detect floating-point ABI before using prebuilt binaries (ARM32, RISC-V)
126
152
  - Forbid duplicate member names in struct types
127
153
 
128
- ## Koffi 1.2.4
154
+ ### Koffi 1.2.4
129
155
 
130
156
  **New features:**
131
157
 
132
158
  - Windows ARM64 is now supported
133
159
 
134
- ## Koffi 1.2.3
160
+ ### Koffi 1.2.3
135
161
 
136
162
  **New features:**
137
163
 
138
164
  - A prebuilt binary for macOS ARM64 (M1) is now included
139
165
 
140
- ## Koffi 1.2.1
166
+ ### Koffi 1.2.1
141
167
 
142
168
  This entry documents changes since version 1.1.0.
143
169
 
package/README.md CHANGED
@@ -23,6 +23,12 @@ RISC-V 64 [^3] | ⬜️ *N/A* | ✅ Yes | ⬜️ *N/A* | 🟨 Probab
23
23
 
24
24
  Go to the web site for more information: https://koffi.dev/
25
25
 
26
+ # Project history
27
+
28
+ You can consult the [changelog](https://koffi.dev/changes) on the official website.
29
+
30
+ Major version increments can include breaking API changes, use the [migration guide](https://koffi.dev/changes#migration-guide) for more information.
31
+
26
32
  # License
27
33
 
28
34
  This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
package/doc/benchmarks.md CHANGED
@@ -10,8 +10,8 @@ Here is a quick overview of the execution time of Koffi calls on three benchmark
10
10
 
11
11
  <table style="margin: 0 auto;">
12
12
  <tr>
13
- <td><a href="_static/perf_linux_20220628.png" target="_blank"><img src="_static/perf_linux_20220628.png" alt="Linux x86_64 performance" style="width: 350px;"/></a></td>
14
- <td><a href="_static/perf_windows_20220628.png" target="_blank"><img src="_static/perf_windows_20220628.png" alt="Windows x86_64 performance" style="width: 350px;"/></a></td>
13
+ <td><a href="static/perf_linux_20220628.png" target="_blank"><img src="static/perf_linux_20220628.png" alt="Linux x86_64 performance" style="width: 350px;"/></a></td>
14
+ <td><a href="static/perf_windows_20220628.png" target="_blank"><img src="static/perf_windows_20220628.png" alt="Windows x86_64 performance" style="width: 350px;"/></a></td>
15
15
  </tr>
16
16
  </table>
17
17
 
package/doc/changes.md CHANGED
@@ -1,2 +1,157 @@
1
1
  ```{include} ../ChangeLog.md
2
- ```
2
+ ```
3
+
4
+ ## Migration guide
5
+
6
+ ### Koffi 1.x to 2.x
7
+
8
+ The API was changed in 2.x in a few ways, in order to reduce some excessively "magic" behavior and reduce the syntax differences between C and the C-like prototypes.
9
+
10
+ You may need to change your code if you use:
11
+
12
+ - Callback functions
13
+ - Opaque handles
14
+ - `koffi.introspect()`
15
+
16
+ #### Callback types
17
+
18
+ In Koffi 1.x, callbacks were defined in a way that made them usable directly as parameter and return types, obscuring the underlying pointer. Now, you must use them through a pointer: `void CallIt(CallbackType func)` in Koffi 1.x becomes `void CallIt(CallbackType *func)` in version 2.0 and newer.
19
+
20
+ Given the following C code:
21
+
22
+ ```c
23
+ #include <string.h>
24
+
25
+ int TransferToJS(const char *name, int age, int (*cb)(const char *str, int age))
26
+ {
27
+ char buf[64];
28
+ snprintf(buf, sizeof(buf), "Hello %s!", str);
29
+ return cb(buf, age);
30
+ }
31
+ ```
32
+
33
+ The two versions below illustrate the API difference between Koffi 1.x and Koffi 2.x:
34
+
35
+ ```js
36
+ // Koffi 1.x
37
+
38
+ const TransferCallback = koffi.callback('int TransferCallback(const char *str, int age)');
39
+
40
+ const TransferToJS = lib.func('TransferToJS', 'int', ['str', 'int', TransferCallback]);
41
+ // Equivalent to: const TransferToJS = lib.func('int TransferToJS(str s, int x, TransferCallback cb)');
42
+
43
+ let ret = TransferToJS('Niels', 27, (str, age) => {
44
+ console.log(str);
45
+ console.log('Your age is:', age);
46
+ return 42;
47
+ });
48
+ console.log(ret);
49
+ ```
50
+
51
+ ```js
52
+ // Koffi 2.x
53
+
54
+ const TransferCallback = koffi.callback('int TransferCallback(const char *str, int age)');
55
+
56
+ const TransferToJS = lib.func('TransferToJS', 'int', ['str', 'int', koffi.pointer(TransferCallback)]);
57
+ // Equivalent to: const TransferToJS = lib.func('int TransferToJS(str s, int x, TransferCallback *cb)');
58
+
59
+ let ret = TransferToJS('Niels', 27, (str, age) => {
60
+ console.log(str);
61
+ console.log('Your age is:', age);
62
+ return 42;
63
+ });
64
+ console.log(ret);
65
+ ```
66
+
67
+ Koffi 1.x only supported [transient callbacks](functions.md#javascript-callbacks), you must use Koffi 2.x for registered callbacks.
68
+
69
+ #### Opaque handles
70
+
71
+ 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. Now, you must use them through a pointer, and use an array for output parameters.
72
+
73
+ For functions that return handles or pass them by parameter:
74
+
75
+ ```js
76
+ // Koffi 1.x
77
+
78
+ const FILE = koffi.handle('FILE');
79
+ const fopen = lib.func('FILE fopen(const char *path, const char *mode)');
80
+ const fclose = lib.func('int fclose(FILE stream)');
81
+
82
+ let fp = fopen('touch', 'wb');
83
+ if (!fp)
84
+ throw new Error('Failed to open file');
85
+ fclose(fp);
86
+ ```
87
+
88
+ ```js
89
+ // Koffi 2.x
90
+
91
+ const FILE = koffi.handle('FILE');
92
+ const fopen = lib.func('FILE *fopen(const char *path, const char *mode)');
93
+ const fclose = lib.func('int fclose(FILE *stream)');
94
+
95
+ let fp = fopen('touch', 'wb');
96
+ if (!fp)
97
+ throw new Error('Failed to open file');
98
+ fclose(fp);
99
+ ```
100
+
101
+ For functions that set opaque handles through output parameters (such as `sqlite3_open_v2`), you must now use a single element array as shown below:
102
+
103
+ ```js
104
+ // Koffi 1.x
105
+
106
+ const sqlite3_db = koffi.handle('sqlite3_db');
107
+
108
+ const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['str', koffi.out(sqlite3_db), 'int', 'str']);
109
+ const sqlite3_close_v2 = lib.func('sqlite3_close_v2', 'int', [sqlite3_db]);
110
+
111
+ const SQLITE_OPEN_READWRITE = 0x2;
112
+ const SQLITE_OPEN_CREATE = 0x4;
113
+
114
+ let db = {};
115
+
116
+ if (sqlite3_open_v2(':memory:', db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, null) != 0)
117
+ throw new Error('Failed to open database');
118
+
119
+ sqlite3_close_v2(db);
120
+ ```
121
+
122
+ ```js
123
+ // Koffi 2.x
124
+
125
+ const sqlite3_db = koffi.handle('sqlite3_db');
126
+
127
+ const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['str', koffi.out(koffi.pointer(sqlite3_db, 2)), 'int', 'str']);
128
+ const sqlite3_close_v2 = lib.func('sqlite3_close_v2', 'int', [koffi.pointer(sqlite3_db)]);
129
+
130
+ const SQLITE_OPEN_READWRITE = 0x2;
131
+ const SQLITE_OPEN_CREATE = 0x4;
132
+
133
+ let db = null;
134
+
135
+ let ptr = [null];
136
+ if (sqlite3_open_v2(':memory:', ptr, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, null) != 0)
137
+ throw new Error('Failed to open database');
138
+ db = ptr[0];
139
+
140
+ sqlite3_close_v2(db);
141
+ ```
142
+
143
+ #### koffi.introspect()
144
+
145
+ In Koffi 1.x, `koffi.introspect()` would only work with struct types, and return the object passed to `koffi.struct()` to initialize the type. Now this function works with all types.
146
+
147
+ You can still get the list of struct members:
148
+
149
+ ```js
150
+ const StructType = koffi.struct('StructType', { dummy: 'int' });
151
+
152
+ // Koffi 1.x
153
+ let members = koffi.introspect(StructType);
154
+
155
+ // Koffi 2.x
156
+ let members = koffi.introspect(StructType).members;
157
+ ```
package/doc/contribute.md CHANGED
@@ -111,7 +111,6 @@ node qemu.js info debian_x64
111
111
 
112
112
  The following features and improvements are planned, not necessarily in that order:
113
113
 
114
- - Provide better ways to automatically deal with caller/heap-allocated memory (strings, etc.)
115
114
  - Optimize passing of structs and arrays (avoid setting named properties one by one? separate HFA-specific helper functions?)
116
115
  - Automate Windows/AArch64 (qemu) and macOS/AArch64 (how? ... thanks Apple) tests
117
116
  - Create a real-world example, using several libraries (Raylib, SQLite, libsodium) to illustrate various C API styles
Binary file
Binary file
Binary file
@@ -1,2 +1,157 @@
1
1
  ```{include} ../ChangeLog.md
2
- ```
2
+ ```
3
+
4
+ ## Migration guide
5
+
6
+ ### Koffi 1.x to 2.x
7
+
8
+ The API was changed in 2.x in a few ways, in order to reduce some excessively "magic" behavior and reduce the syntax differences between C and the C-like prototypes.
9
+
10
+ You may need to change your code if you use:
11
+
12
+ - Callback functions
13
+ - Opaque handles
14
+ - `koffi.introspect()`
15
+
16
+ #### Callback types
17
+
18
+ In Koffi 1.x, callbacks were defined in a way that made them usable directly as parameter and return types, obscuring the underlying pointer. Now, you must use them through a pointer: `void CallIt(CallbackType func)` in Koffi 1.x becomes `void CallIt(CallbackType *func)` in version 2.0 and newer.
19
+
20
+ Given the following C code:
21
+
22
+ ```c
23
+ #include <string.h>
24
+
25
+ int TransferToJS(const char *name, int age, int (*cb)(const char *str, int age))
26
+ {
27
+ char buf[64];
28
+ snprintf(buf, sizeof(buf), "Hello %s!", str);
29
+ return cb(buf, age);
30
+ }
31
+ ```
32
+
33
+ The two versions below illustrate the API difference between Koffi 1.x and Koffi 2.x:
34
+
35
+ ```js
36
+ // Koffi 1.x
37
+
38
+ const TransferCallback = koffi.callback('int TransferCallback(const char *str, int age)');
39
+
40
+ const TransferToJS = lib.func('TransferToJS', 'int', ['str', 'int', TransferCallback]);
41
+ // Equivalent to: const TransferToJS = lib.func('int TransferToJS(str s, int x, TransferCallback cb)');
42
+
43
+ let ret = TransferToJS('Niels', 27, (str, age) => {
44
+ console.log(str);
45
+ console.log('Your age is:', age);
46
+ return 42;
47
+ });
48
+ console.log(ret);
49
+ ```
50
+
51
+ ```js
52
+ // Koffi 2.x
53
+
54
+ const TransferCallback = koffi.callback('int TransferCallback(const char *str, int age)');
55
+
56
+ const TransferToJS = lib.func('TransferToJS', 'int', ['str', 'int', koffi.pointer(TransferCallback)]);
57
+ // Equivalent to: const TransferToJS = lib.func('int TransferToJS(str s, int x, TransferCallback *cb)');
58
+
59
+ let ret = TransferToJS('Niels', 27, (str, age) => {
60
+ console.log(str);
61
+ console.log('Your age is:', age);
62
+ return 42;
63
+ });
64
+ console.log(ret);
65
+ ```
66
+
67
+ Koffi 1.x only supported [transient callbacks](functions.md#javascript-callbacks), you must use Koffi 2.x for registered callbacks.
68
+
69
+ #### Opaque handles
70
+
71
+ 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. Now, you must use them through a pointer, and use an array for output parameters.
72
+
73
+ For functions that return handles or pass them by parameter:
74
+
75
+ ```js
76
+ // Koffi 1.x
77
+
78
+ const FILE = koffi.handle('FILE');
79
+ const fopen = lib.func('FILE fopen(const char *path, const char *mode)');
80
+ const fclose = lib.func('int fclose(FILE stream)');
81
+
82
+ let fp = fopen('touch', 'wb');
83
+ if (!fp)
84
+ throw new Error('Failed to open file');
85
+ fclose(fp);
86
+ ```
87
+
88
+ ```js
89
+ // Koffi 2.x
90
+
91
+ const FILE = koffi.handle('FILE');
92
+ const fopen = lib.func('FILE *fopen(const char *path, const char *mode)');
93
+ const fclose = lib.func('int fclose(FILE *stream)');
94
+
95
+ let fp = fopen('touch', 'wb');
96
+ if (!fp)
97
+ throw new Error('Failed to open file');
98
+ fclose(fp);
99
+ ```
100
+
101
+ For functions that set opaque handles through output parameters (such as `sqlite3_open_v2`), you must now use a single element array as shown below:
102
+
103
+ ```js
104
+ // Koffi 1.x
105
+
106
+ const sqlite3_db = koffi.handle('sqlite3_db');
107
+
108
+ const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['str', koffi.out(sqlite3_db), 'int', 'str']);
109
+ const sqlite3_close_v2 = lib.func('sqlite3_close_v2', 'int', [sqlite3_db]);
110
+
111
+ const SQLITE_OPEN_READWRITE = 0x2;
112
+ const SQLITE_OPEN_CREATE = 0x4;
113
+
114
+ let db = {};
115
+
116
+ if (sqlite3_open_v2(':memory:', db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, null) != 0)
117
+ throw new Error('Failed to open database');
118
+
119
+ sqlite3_close_v2(db);
120
+ ```
121
+
122
+ ```js
123
+ // Koffi 2.x
124
+
125
+ const sqlite3_db = koffi.handle('sqlite3_db');
126
+
127
+ const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['str', koffi.out(koffi.pointer(sqlite3_db, 2)), 'int', 'str']);
128
+ const sqlite3_close_v2 = lib.func('sqlite3_close_v2', 'int', [koffi.pointer(sqlite3_db)]);
129
+
130
+ const SQLITE_OPEN_READWRITE = 0x2;
131
+ const SQLITE_OPEN_CREATE = 0x4;
132
+
133
+ let db = null;
134
+
135
+ let ptr = [null];
136
+ if (sqlite3_open_v2(':memory:', ptr, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, null) != 0)
137
+ throw new Error('Failed to open database');
138
+ db = ptr[0];
139
+
140
+ sqlite3_close_v2(db);
141
+ ```
142
+
143
+ #### koffi.introspect()
144
+
145
+ In Koffi 1.x, `koffi.introspect()` would only work with struct types, and return the object passed to `koffi.struct()` to initialize the type. Now this function works with all types.
146
+
147
+ You can still get the list of struct members:
148
+
149
+ ```js
150
+ const StructType = koffi.struct('StructType', { dummy: 'int' });
151
+
152
+ // Koffi 1.x
153
+ let members = koffi.introspect(StructType);
154
+
155
+ // Koffi 2.x
156
+ let members = koffi.introspect(StructType).members;
157
+ ```
@@ -1,4 +1,4 @@
1
- # Function calls
1
+ # Functions
2
2
 
3
3
  ## Function definitions
4
4
 
@@ -158,7 +158,7 @@ This example opens an in-memory SQLite database, and uses the node-ffi-style fun
158
158
 
159
159
  ```js
160
160
  const koffi = require('koffi');
161
- const lib = koffi.load('sqlite.so');
161
+ const lib = koffi.load('sqlite3.so');
162
162
 
163
163
  const sqlite3_db = koffi.handle('sqlite3_db');
164
164
 
@@ -169,9 +169,11 @@ const sqlite3_close_v2 = lib.func('sqlite3_close_v2', 'int', [koffi.pointer(sqli
169
169
  const SQLITE_OPEN_READWRITE = 0x2;
170
170
  const SQLITE_OPEN_CREATE = 0x4;
171
171
 
172
- let db = {};
173
- if (sqlite3_open_v2(':memory:', db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, null) != 0)
172
+ let out = [null];
173
+ if (sqlite3_open_v2(':memory:', out, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, null) != 0)
174
174
  throw new Error('Failed to open database');
175
+ let db = out[0];
176
+
175
177
  sqlite3_close_v2(db);
176
178
  ```
177
179
 
@@ -246,6 +248,8 @@ Callbacks **have changed in version 2.0**.
246
248
  In Koffi 1.x, callbacks were defined in a way that made them usable directly as parameter and return types, obscuring the underlying pointer.
247
249
 
248
250
  Now, you must use them through a pointer: `void CallIt(CallbackType func)` in Koffi 1.x becomes `void CallIt(CallbackType *func)` in version 2.0 and newer.
251
+
252
+ Consult the [migration guide](changes.md) for more information.
249
253
  ```
250
254
 
251
255
  Koffi only uses predefined static trampolines, and does not need to generate code at runtime, which makes it compatible with platforms with hardened W^X migitations (such as PaX mprotect). However, this imposes some restrictions on the maximum number of callbacks, and their duration.
@@ -154,6 +154,8 @@ Opaque handles **have changed in version 2.0**.
154
154
  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
155
 
156
156
  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
+
158
+ Consult the [migration guide](changes.md) for more information.
157
159
  ```
158
160
 
159
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`.
@@ -520,11 +522,14 @@ Koffi exposes three functions to explore type information:
520
522
  - `koffi.sizeof(type)` to get the size of a type
521
523
  - `koffi.alignof(type)` to get the alignment of a type
522
524
  - `koffi.introspect(type)` to get the definition of a type in an object containing: name, primitive, size, alignment, members (structs), reference (array, pointer) and length (array)
525
+ - `koffi.resolve(type)` to get the resolved type object from a type string
523
526
 
524
527
  ```{note}
525
528
  The value returned by `introspect()` has **changed in version 2.0**.
526
529
 
527
530
  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.
531
+
532
+ Consult the [migration guide](changes.md) for more information.
528
533
  ```
529
534
 
530
535
  Just like before, you can refer to primitive types by their name or through `koffi.types`:
@@ -534,3 +539,7 @@ Just like before, you can refer to primitive types by their name or through `kof
534
539
  console.log(koffi.sizeof('long'));
535
540
  console.log(koffi.sizeof(koffi.types.long));
536
541
  ```
542
+
543
+ ## Type aliasing
544
+
545
+ You can alias a type with `koffi.alias(name, type)`. Aliased types are completely equivalent.
@@ -165,7 +165,7 @@
165
165
  <li class="toctree-l1"><a class="reference internal" href="platforms">Requirements</a></li>
166
166
  <li class="toctree-l1"><a class="reference internal" href="start">Quick start</a></li>
167
167
  <li class="toctree-l1"><a class="reference internal" href="types">Data types</a></li>
168
- <li class="toctree-l1"><a class="reference internal" href="functions">Function calls</a></li>
168
+ <li class="toctree-l1"><a class="reference internal" href="functions">Functions</a></li>
169
169
  <li class="toctree-l1"><a class="reference internal" href="memory">Memory usage</a></li>
170
170
  <li class="toctree-l1 current current-page"><a class="current reference internal" href="#">Benchmarks</a></li>
171
171
  <li class="toctree-l1"><a class="reference internal" href="contribute">Contributing</a></li>