koffi 2.5.2 → 2.5.4

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 (39) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +1 -1
  3. package/build/{2.5.2 → 2.5.4}/koffi_darwin_arm64/koffi.node +0 -0
  4. package/build/{2.5.2 → 2.5.4}/koffi_darwin_x64/koffi.node +0 -0
  5. package/build/{2.5.2 → 2.5.4}/koffi_freebsd_arm64/koffi.node +0 -0
  6. package/build/{2.5.2 → 2.5.4}/koffi_freebsd_ia32/koffi.node +0 -0
  7. package/build/{2.5.2 → 2.5.4}/koffi_freebsd_x64/koffi.node +0 -0
  8. package/build/2.5.4/koffi_linux_arm32hf/koffi.node +0 -0
  9. package/build/{2.5.2 → 2.5.4}/koffi_linux_arm64/koffi.node +0 -0
  10. package/build/2.5.4/koffi_linux_ia32/koffi.node +0 -0
  11. package/build/{2.5.2 → 2.5.4}/koffi_linux_riscv64hf64/koffi.node +0 -0
  12. package/build/{2.5.2 → 2.5.4}/koffi_linux_x64/koffi.node +0 -0
  13. package/build/{2.5.2 → 2.5.4}/koffi_openbsd_ia32/koffi.node +0 -0
  14. package/build/{2.5.2 → 2.5.4}/koffi_openbsd_x64/koffi.node +0 -0
  15. package/build/2.5.4/koffi_win32_arm64/koffi.node +0 -0
  16. package/build/{2.5.2 → 2.5.4}/koffi_win32_ia32/koffi.node +0 -0
  17. package/build/{2.5.2 → 2.5.4}/koffi_win32_x64/koffi.node +0 -0
  18. package/doc/callbacks.md +7 -0
  19. package/doc/functions.md +6 -0
  20. package/doc/misc.md +2 -0
  21. package/doc/parameters.md +14 -0
  22. package/doc/pointers.md +4 -0
  23. package/doc/start.md +7 -1
  24. package/doc/types.md +3 -0
  25. package/doc/unions.md +1 -0
  26. package/package.json +2 -2
  27. package/src/core/libcc/libcc.hh +0 -2
  28. package/src/index.d.ts +12 -7
  29. package/src/koffi/src/ffi.cc +14 -12
  30. package/src/koffi/src/util.cc +1 -1
  31. package/build/2.5.2/koffi_linux_arm32hf/koffi.node +0 -0
  32. package/build/2.5.2/koffi_linux_ia32/koffi.node +0 -0
  33. package/build/2.5.2/koffi_win32_arm64/koffi.node +0 -0
  34. /package/build/{2.5.2 → 2.5.4}/koffi_win32_arm64/koffi.exp +0 -0
  35. /package/build/{2.5.2 → 2.5.4}/koffi_win32_arm64/koffi.lib +0 -0
  36. /package/build/{2.5.2 → 2.5.4}/koffi_win32_ia32/koffi.exp +0 -0
  37. /package/build/{2.5.2 → 2.5.4}/koffi_win32_ia32/koffi.lib +0 -0
  38. /package/build/{2.5.2 → 2.5.4}/koffi_win32_x64/koffi.exp +0 -0
  39. /package/build/{2.5.2 → 2.5.4}/koffi_win32_x64/koffi.lib +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,23 @@
4
4
 
5
5
  ### Koffi 2.5
6
6
 
7
+ #### Koffi 2.5.4
8
+
9
+ **Main changes:**
10
+
11
+ - Fix koffi.pointer() not accepting disposable types
12
+
13
+ **Other changes:**
14
+
15
+ - Fix potential issues when making pointer to anonymous types
16
+
17
+ #### Koffi 2.5.3
18
+
19
+ **Main changes:**
20
+
21
+ - Add missing union exports in TS definition file
22
+ - Fix some parameter names in TS definition file
23
+
7
24
  #### Koffi 2.5.2
8
25
 
9
26
  **Main changes:**
package/README.md CHANGED
@@ -19,7 +19,7 @@ RISC-V 64 [^3] | ⬜️ *N/A* | ✅ Yes | ⬜️ *N/A* | 🟨 Probab
19
19
 
20
20
  [^1]: The following call conventions are supported: cdecl, stdcall, MS fastcall, thiscall.
21
21
  [^2]: The prebuilt binary uses the hard float ABI and expects a VFP coprocessor. Build from source to use Koffi with a different ABI (softfp, soft).
22
- [^3]: The prebuilt binary uses the LP64D (double-precision float) ABI. The LP64 ABI is supported in theory if you build Koffi from source (untested), the LP64F ABI is not supported.
22
+ [^3]: The prebuilt binary uses the LP64D (double-precision float) ABI. The LP64 ABI is supported in theory if you build Koffi from source but this is untested. The LP64F ABI is not supported.
23
23
 
24
24
  Go to the web site for more information: https://koffi.dev/
25
25
 
package/doc/callbacks.md CHANGED
@@ -11,6 +11,7 @@ The function `koffi.proto()` was introduced in Koffi 2.4, it was called `koffi.c
11
11
  In order to pass a JS function to a C function expecting a callback, you must first create a callback type with the expected return type and parameters. The syntax is similar to the one used to load functions from a shared library.
12
12
 
13
13
  ```js
14
+ // ES6 syntax: import koffi from 'koffi';
14
15
  const koffi = require('koffi');
15
16
 
16
17
  // With the classic syntax, this callback expects an integer and returns nothing
@@ -59,7 +60,9 @@ int TransferToJS(const char *name, int age, int (*cb)(const char *str, int age))
59
60
  ```
60
61
 
61
62
  ```js
63
+ // ES6 syntax: import koffi from 'koffi';
62
64
  const koffi = require('koffi');
65
+
63
66
  const lib = koffi.load('./callbacks.so'); // Fake path
64
67
 
65
68
  const TransferCallback = koffi.proto('int TransferCallback(const char *str, int age)');
@@ -107,7 +110,9 @@ void SayIt(const char *name)
107
110
  ```
108
111
 
109
112
  ```js
113
+ // ES6 syntax: import koffi from 'koffi';
110
114
  const koffi = require('koffi');
115
+
111
116
  const lib = koffi.load('./callbacks.so'); // Fake path
112
117
 
113
118
  const GetCallback = koffi.proto('const char *GetCallback(const char *name)');
@@ -158,7 +163,9 @@ Some arguments are optional and this function can be called in several ways:
158
163
  The following example sorts an array of strings (in-place) with `qsort()`:
159
164
 
160
165
  ```js
166
+ // ES6 syntax: import koffi from 'koffi';
161
167
  const koffi = require('koffi');
168
+
162
169
  const lib = koffi.load('libc.so.6');
163
170
 
164
171
  const SortCallback = koffi.proto('int SortCallback(const void *first, const void *second)');
package/doc/functions.md CHANGED
@@ -5,7 +5,9 @@
5
5
  To declare functions, start by loading the shared library with `koffi.load(filename)`.
6
6
 
7
7
  ```js
8
+ // ES6 syntax: import koffi from 'koffi';
8
9
  const koffi = require('koffi');
10
+
9
11
  const lib = koffi.load('/path/to/shared/library'); // File extension depends on platforms: .so, .dll, .dylib, etc.
10
12
  ````
11
13
 
@@ -81,7 +83,9 @@ You can safely use these on non-x86 platforms, they are simply ignored.
81
83
  Below you can find a small example showing how to use a non-default calling convention, with the two syntaxes:
82
84
 
83
85
  ```js
86
+ // ES6 syntax: import koffi from 'koffi';
84
87
  const koffi = require('koffi');
88
+
85
89
  const lib = koffi.load('user32.dll');
86
90
 
87
91
  // The following two declarations are equivalent, and use stdcall on x86 (and the default ABI on other platforms)
@@ -116,7 +120,9 @@ printf('Integer %d, double %g, str %s', 'int', 6, 'double', 8.5, 'str', 'THE END
116
120
  You can issue asynchronous calls by calling the function through its async member. In this case, you need to provide a callback function as the last argument, with `(err, res)` parameters.
117
121
 
118
122
  ```js
123
+ // ES6 syntax: import koffi from 'koffi';
119
124
  const koffi = require('koffi');
125
+
120
126
  const lib = koffi.load('libc.so.6');
121
127
 
122
128
  const atoi = lib.func('int atoi(const char *str)');
package/doc/misc.md CHANGED
@@ -112,6 +112,8 @@ The standard POSIX error codes are available in `koffi.os.errno`, as in the exam
112
112
 
113
113
  ```js
114
114
  const assert = require('assert');
115
+
116
+ // ES6 syntax: import koffi from 'koffi';
115
117
  const koffi = require('koffi');
116
118
 
117
119
  const lib = koffi.load('libc.so.6');
package/doc/parameters.md CHANGED
@@ -28,7 +28,9 @@ The same can be done when declaring a function with a C-like prototype string, w
28
28
  This Windows example enumerate all Chrome windows along with their PID and their title. The `GetWindowThreadProcessId()` function illustrates how to get a primitive value from an output argument.
29
29
 
30
30
  ```js
31
+ // ES6 syntax: import koffi from 'koffi';
31
32
  const koffi = require('koffi');
33
+
32
34
  const user32 = koffi.load('user32.dll');
33
35
 
34
36
  const DWORD = koffi.alias('DWORD', 'uint32_t');
@@ -82,7 +84,9 @@ for (let hwnd = null;;) {
82
84
  This example calls the POSIX function `gettimeofday()`, and uses the prototype-like syntax.
83
85
 
84
86
  ```js
87
+ // ES6 syntax: import koffi from 'koffi';
85
88
  const koffi = require('koffi');
89
+
86
90
  const lib = koffi.load('libc.so.6');
87
91
 
88
92
  const timeval = koffi.struct('timeval', {
@@ -108,7 +112,9 @@ console.log(tv);
108
112
  This example opens an in-memory SQLite database, and uses the node-ffi-style function declaration syntax.
109
113
 
110
114
  ```js
115
+ // ES6 syntax: import koffi from 'koffi';
111
116
  const koffi = require('koffi');
117
+
112
118
  const lib = koffi.load('sqlite3.so');
113
119
 
114
120
  const sqlite3 = koffi.opaque('sqlite3');
@@ -182,7 +188,9 @@ Koffi provides two features to deal with this:
182
188
  The example below shows the use of `koffi.as()` to read the header of a PNG file with `fread()`.
183
189
 
184
190
  ```js
191
+ // ES6 syntax: import koffi from 'koffi';
185
192
  const koffi = require('koffi');
193
+
186
194
  const lib = koffi.load('libc.so.6');
187
195
 
188
196
  const FILE = koffi.opaque('FILE');
@@ -238,7 +246,9 @@ You can use buffers and typed arrays for output (and input/output) pointer param
238
246
  Once the native function returns, you can decode the content with `koffi.decode(value, type)` as in the following example:
239
247
 
240
248
  ```js
249
+ // ES6 syntax: import koffi from 'koffi';
241
250
  const koffi = require('koffi');
251
+
242
252
  const lib = koffi.load('libc.so.6');
243
253
 
244
254
  const Vec3 = koffi.struct('Vec3', {
@@ -292,7 +302,9 @@ const ExplicitFree = koffi.disposable('HeapStr16', 'str16', koffi.free); // You
292
302
  The following example illustrates the use of a disposable type derived from *str*.
293
303
 
294
304
  ```js
305
+ // ES6 syntax: import koffi from 'koffi';
295
306
  const koffi = require('koffi');
307
+
296
308
  const lib = koffi.load('libc.so.6');
297
309
 
298
310
  const HeapStr = koffi.disposable('str');
@@ -305,7 +317,9 @@ console.log(copy); // Prints Hello!
305
317
  When you declare functions with the [prototype-like syntax](functions.md#definition-syntax), you can either use named disposable types or use the '!' shortcut qualifier with compatibles types, as shown in the example below. This qualifier creates an anonymous disposable type that calls `koffi.free(ptr)`.
306
318
 
307
319
  ```js
320
+ // ES6 syntax: import koffi from 'koffi';
308
321
  const koffi = require('koffi');
322
+
309
323
  const lib = koffi.load('libc.so.6');
310
324
 
311
325
  // You can also use: const strdup = lib.func('const char *! strdup(const char *str)')
package/doc/pointers.md CHANGED
@@ -16,7 +16,9 @@ In C, pointer arguments are used for differenty purposes. It is important to dis
16
16
  The following Win32 example uses `GetCursorPos()` (with an output parameter) to retrieve and show the current cursor position.
17
17
 
18
18
  ```js
19
+ // ES6 syntax: import koffi from 'koffi';
19
20
  const koffi = require('koffi');
21
+
20
22
  const lib = koffi.load('kernel32.dll');
21
23
 
22
24
  // Type declarations
@@ -115,7 +117,9 @@ int64_t ComputeTotalLength(const char **strings)
115
117
  ```
116
118
 
117
119
  ```js
120
+ // ES6 syntax: import koffi from 'koffi';
118
121
  const koffi = require('koffi');
122
+
119
123
  const lib = koffi.load('./length.so');
120
124
 
121
125
  const ComputeTotalLength = lib.func('int64_t ComputeTotalLength(const char **strings)');
package/doc/start.md CHANGED
@@ -8,10 +8,14 @@ You can install Koffi with npm:
8
8
  npm install koffi
9
9
  ```
10
10
 
11
- Once you have installed Koffi, you can start by loading it this way:
11
+ Once you have installed Koffi, you can start by loading it:
12
12
 
13
13
  ```js
14
+ // CommonJS syntax
14
15
  const koffi = require('koffi');
16
+
17
+ // ES6 modules
18
+ import koffi from 'koffi';
15
19
  ```
16
20
 
17
21
  Below you can find three examples:
@@ -26,6 +30,7 @@ This is a small example for Linux systems, which uses `gettimeofday()`, `localti
26
30
  It illustrates the use of output parameters.
27
31
 
28
32
  ```js
33
+ // ES6 syntax: import koffi from 'koffi';
29
34
  const koffi = require('koffi');
30
35
 
31
36
  // Load the shared library
@@ -76,6 +81,7 @@ This is a small example targeting the Win32 API, using `MessageBox()` to show a
76
81
  It illustrates the use of the x86 stdcall calling convention, and the use of UTF-8 and UTF-16 string arguments.
77
82
 
78
83
  ```js
84
+ // ES6 syntax: import koffi from 'koffi';
79
85
  const koffi = require('koffi');
80
86
 
81
87
  // Load the shared library
package/doc/types.md CHANGED
@@ -278,7 +278,9 @@ const char *ConcatBuild(Concat *c)
278
278
  ```
279
279
 
280
280
  ```js
281
+ // ES6 syntax: import koffi from 'koffi';
281
282
  const koffi = require('koffi');
283
+
282
284
  const lib = koffi.load('./handles.so');
283
285
 
284
286
  const Concat = koffi.opaque('Concat');
@@ -344,6 +346,7 @@ Koffi applies the following conversion rules when passing arrays to/from C:
344
346
  See the example below:
345
347
 
346
348
  ```js
349
+ // ES6 syntax: import koffi from 'koffi';
347
350
  const koffi = require('koffi');
348
351
 
349
352
  // Those two structs are exactly the same, only the array conversion hint is different
package/doc/unions.md CHANGED
@@ -58,6 +58,7 @@ DoSomething('string', { .str = 'Hello!' });
58
58
  The following example uses the [SendInput](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput) Win32 API to emit the Win+D shortcut and hide windows (show the desktop).
59
59
 
60
60
  ```js
61
+ // ES6 syntax: import koffi from 'koffi';
61
62
  const koffi = require('koffi');
62
63
 
63
64
  // Win32 type and functions
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.5.2",
4
- "stable": "2.5.2",
3
+ "version": "2.5.4",
4
+ "stable": "2.5.4",
5
5
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
6
6
  "keywords": [
7
7
  "foreign",
@@ -3906,8 +3906,6 @@ enum class StatResult {
3906
3906
 
3907
3907
  MissingPath,
3908
3908
  AccessDenied,
3909
- PartialEnum,
3910
- CallbackFail,
3911
3909
  OtherError
3912
3910
  };
3913
3911
 
package/src/index.d.ts CHANGED
@@ -86,8 +86,13 @@ declare module 'koffi' {
86
86
  export function pack(name: string, def: Record<string, TypeSpecWithAlignment>): IKoffiCType;
87
87
  export function pack(def: Record<string, TypeSpecWithAlignment>): IKoffiCType;
88
88
 
89
- // export function union(name: string, def: Record<string, TypeSpecWithAlignment>): IKoffiCType;
90
- // export function union(def: Record<string, TypeSpecWithAlignment>): IKoffiCType;
89
+ export function union(name: string, def: Record<string, TypeSpecWithAlignment>): IKoffiCType;
90
+ export function union(def: Record<string, TypeSpecWithAlignment>): IKoffiCType;
91
+
92
+ export class Union {
93
+ constructor(type: TypeSpec);
94
+ [s: string]: any;
95
+ }
91
96
 
92
97
  export function array(ref: TypeSpec, len: number, hint?: ArrayHint | null): IKoffiCType;
93
98
 
@@ -96,12 +101,12 @@ declare module 'koffi' {
96
101
  /** @deprecated */ export function handle(name: string): IKoffiCType;
97
102
  /** @deprecated */ export function handle(): IKoffiCType;
98
103
 
99
- export function pointer(value: TypeSpec): IKoffiCType;
100
- export function pointer(value: TypeSpec, asteriskCount: number): IKoffiCType;
101
- export function pointer(name: string, value: TypeSpec, asteriskCount: number): IKoffiCType;
104
+ export function pointer(ref: TypeSpec): IKoffiCType;
105
+ export function pointer(ref: TypeSpec, asteriskCount: number): IKoffiCType;
106
+ export function pointer(name: string, ref: TypeSpec, asteriskCount: number): IKoffiCType;
102
107
 
103
- export function out(value: TypeSpec): IKoffiCType;
104
- export function inout(value: TypeSpec): IKoffiCType;
108
+ export function out(type: TypeSpec): IKoffiCType;
109
+ export function inout(type: TypeSpec): IKoffiCType;
105
110
 
106
111
  export function disposable(type: TypeSpec): IKoffiCType;
107
112
  export function disposable(name: string, type: TypeSpec): IKoffiCType;
@@ -228,11 +228,12 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
228
228
  TypeInfo *type = instance->types.AppendDefault();
229
229
  RG_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
230
230
 
231
- std::string name = named ? info[0].As<Napi::String>() : std::string("<anonymous>");
231
+ Napi::String name = info[0].As<Napi::String>();
232
232
  Napi::Object obj = info[named].As<Napi::Object>();
233
233
  Napi::Array keys = obj.GetPropertyNames();
234
234
 
235
- type->name = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
235
+ type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
236
+ : Fmt(&instance->str_alloc, "<type_%1>", instance->types.len).ptr;
236
237
 
237
238
  type->primitive = PrimitiveKind::Record;
238
239
  type->align = 1;
@@ -356,11 +357,12 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
356
357
  TypeInfo *type = instance->types.AppendDefault();
357
358
  RG_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
358
359
 
359
- std::string name = named ? info[0].As<Napi::String>() : std::string("<anonymous>");
360
+ Napi::String name = info[0].As<Napi::String>();
360
361
  Napi::Object obj = info[named].As<Napi::Object>();
361
362
  Napi::Array keys = obj.GetPropertyNames();
362
363
 
363
- type->name = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
364
+ type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
365
+ : Fmt(&instance->str_alloc, "<type_%1>", instance->types.len).ptr;
364
366
 
365
367
  type->primitive = PrimitiveKind::Union;
366
368
  type->align = 1;
@@ -485,12 +487,13 @@ static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
485
487
  return env.Null();
486
488
  }
487
489
 
488
- std::string name = named ? info[0].As<Napi::String>() : std::string("<anonymous>");
490
+ Napi::String name = info[0].As<Napi::String>();
489
491
 
490
492
  TypeInfo *type = instance->types.AppendDefault();
491
493
  RG_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
492
494
 
493
- type->name = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
495
+ type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
496
+ : Fmt(&instance->str_alloc, "<type_%1>", instance->types.len).ptr;
494
497
 
495
498
  type->primitive = PrimitiveKind::Void;
496
499
  type->size = 0;
@@ -533,10 +536,6 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
533
536
  const TypeInfo *type = ResolveType(info[named]);
534
537
  if (!type)
535
538
  return env.Null();
536
- if (type->dispose) {
537
- ThrowError<Napi::TypeError>(env, "Cannot create pointer to disposable type '%1'", type->name);
538
- return env.Null();
539
- }
540
539
 
541
540
  int count = 0;
542
541
  if (info.Length() >= 2u + named) {
@@ -642,7 +641,7 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
642
641
  return env.Null();
643
642
  }
644
643
 
645
- std::string name = named ? info[0].As<Napi::String>() : std::string("<anonymous>");
644
+ Napi::String name = info[0].As<Napi::String>();
646
645
 
647
646
  const TypeInfo *src = ResolveType(info[named]);
648
647
  if (!src)
@@ -697,8 +696,11 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
697
696
  RG_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
698
697
 
699
698
  memcpy((void *)type, (const void *)src, RG_SIZE(*src));
700
- type->name = DuplicateString(name.c_str(), &instance->str_alloc).ptr;
701
699
  type->members.allocator = GetNullAllocator();
700
+
701
+ type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
702
+ : Fmt(&instance->str_alloc, "<type_%1>", instance->types.len).ptr;
703
+
702
704
  type->dispose = dispose;
703
705
  type->dispose_ref = Napi::Persistent(dispose_func);
704
706
 
@@ -243,7 +243,7 @@ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str, int *out_direct
243
243
  TypeInfo *copy = instance->types.AppendDefault();
244
244
 
245
245
  memcpy((void *)copy, (const void *)type, RG_SIZE(*type));
246
- copy->name = "<anonymous>";
246
+ copy->name = Fmt(&instance->str_alloc, "<type_%1>", instance->types.len).ptr;
247
247
  copy->members.allocator = GetNullAllocator();
248
248
 
249
249
  copy->dispose = [](Napi::Env env, const TypeInfo *, const void *ptr) {