koffi 3.0.0-alpha.7 → 3.0.0-alpha.9
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.
- package/CHANGELOG.md +30 -0
- package/LICENSE.txt +1 -1
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_arm64/koffi.node +0 -0
- package/build/koffi/musl_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/{bin → build}/koffi/win32_ia32/koffi.exp +0 -0
- package/{bin → build}/koffi/win32_ia32/koffi.node +0 -0
- package/{bin → build}/koffi/win32_x64/koffi.exp +0 -0
- package/{bin → build}/koffi/win32_x64/koffi.node +0 -0
- package/{build.cjs → cnoke.cjs} +2 -2
- package/doc/callbacks.md +9 -9
- package/doc/contribute.md +1 -1
- package/doc/functions.md +6 -6
- package/doc/input.md +70 -6
- package/doc/misc.md +14 -15
- package/doc/output.md +10 -10
- package/doc/packaging.md +6 -6
- package/doc/pointers.md +14 -16
- package/doc/start.md +4 -4
- package/doc/unions.md +2 -2
- package/doc/variables.md +4 -4
- package/index.d.ts +94 -95
- package/lib/native/base/base.cc +8 -6
- package/lib/native/base/base.hh +9 -2
- package/lib/native/base/unicode.inc +1 -1
- package/package.json +3 -3
- package/src/koffi/CMakeLists.txt +4 -4
- package/src/koffi/index.cjs +43 -23
- package/src/koffi/index.js +37 -20
- package/src/koffi/indirect.cjs +43 -23
- package/src/koffi/indirect.js +23 -6
- package/src/koffi/src/abi/arm32.cc +3 -3
- package/src/koffi/src/abi/arm32_asm.S +1 -1
- package/src/koffi/src/abi/arm64.cc +9 -7
- package/src/koffi/src/abi/arm64_asm.S +1 -1
- package/src/koffi/src/abi/arm64_asm.asm +1 -1
- package/src/koffi/src/abi/loong64.cc +1 -1
- package/src/koffi/src/abi/loong64_asm.S +1 -1
- package/src/koffi/src/abi/riscv64.cc +3 -3
- package/src/koffi/src/abi/riscv64_asm.S +1 -1
- package/src/koffi/src/abi/x64sysv.cc +7 -7
- package/src/koffi/src/abi/x64sysv_asm.S +1 -1
- package/src/koffi/src/abi/x64win.cc +7 -7
- package/src/koffi/src/abi/x64win_asm.S +1 -1
- package/src/koffi/src/abi/x64win_asm.asm +1 -1
- package/src/koffi/src/abi/x86.cc +7 -7
- package/src/koffi/src/abi/x86_asm.S +1 -1
- package/src/koffi/src/abi/x86_asm.asm +1 -1
- package/src/koffi/src/call.cc +17 -9
- package/src/koffi/src/call.hh +1 -1
- package/src/koffi/src/errno.inc +1 -1
- package/src/koffi/src/ffi.cc +254 -257
- package/src/koffi/src/ffi.hh +49 -12
- package/src/koffi/src/parser.cc +1 -1
- package/src/koffi/src/parser.hh +1 -1
- package/src/koffi/src/primitives.inc +1 -1
- package/src/koffi/src/{trampolines.js → trampolines.cjs} +2 -2
- package/src/koffi/src/util.cc +300 -77
- package/src/koffi/src/util.hh +48 -18
- package/src/koffi/src/uv.cc +36 -19
- package/src/koffi/src/uv.def +1 -0
- package/src/koffi/src/uv.hh +27 -6
- package/src/koffi/src/win32.cc +1 -1
- package/src/koffi/src/win32.hh +1 -1
- package/vendor/node-addon-api/napi-inl.h +28 -28
- package/bin/koffi/darwin_arm64/koffi.node +0 -0
- package/bin/koffi/darwin_x64/koffi.node +0 -0
- package/bin/koffi/freebsd_arm64/koffi.node +0 -0
- package/bin/koffi/freebsd_ia32/koffi.node +0 -0
- package/bin/koffi/freebsd_x64/koffi.node +0 -0
- package/bin/koffi/linux_arm64/koffi.node +0 -0
- package/bin/koffi/linux_ia32/koffi.node +0 -0
- package/bin/koffi/linux_x64/koffi.node +0 -0
- package/bin/koffi/musl_arm64/koffi.node +0 -0
- package/bin/koffi/musl_x64/koffi.node +0 -0
- package/bin/koffi/openbsd_ia32/koffi.node +0 -0
- package/bin/koffi/openbsd_x64/koffi.node +0 -0
- /package/{bin → build}/koffi/win32_ia32/koffi.lib +0 -0
- /package/{bin → build}/koffi/win32_x64/koffi.lib +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,36 @@
|
|
|
3
3
|
> [!NOTE]
|
|
4
4
|
> Consult the [migration guide](migration) to migrate between major Koffi versions.
|
|
5
5
|
|
|
6
|
+
## Koffi 3
|
|
7
|
+
|
|
8
|
+
### Koffi 3.0
|
|
9
|
+
|
|
10
|
+
#### Koffi 3.0.0 (WIP)
|
|
11
|
+
|
|
12
|
+
**Main changes:**
|
|
13
|
+
|
|
14
|
+
- Replace use of externals with type objects:
|
|
15
|
+
* Use `koffi.type()` to resolve type specifiers (strings or objects) to type objects
|
|
16
|
+
* Access type information directly on type variables without `koffi.introspect()`
|
|
17
|
+
- Replace use of externals with BigInt pointers
|
|
18
|
+
- Rewrite call preparation and execution for vastly improved performance
|
|
19
|
+
|
|
20
|
+
**Other changes:**
|
|
21
|
+
|
|
22
|
+
- Add `koffi.enumeration()` to create [enum types](input#enum-types)
|
|
23
|
+
|
|
24
|
+
**Newly deprecated functions:**
|
|
25
|
+
|
|
26
|
+
- Deprecate `koffi.resolve()` function, replace with `koffi.type()`
|
|
27
|
+
- Deprecate `koffi.introspect()` function, replace with `koffi.type()`
|
|
28
|
+
|
|
29
|
+
**Removed deprecated functions:**
|
|
30
|
+
|
|
31
|
+
- Remove `koffi.callback()` long replaced with `koffi.proto()`
|
|
32
|
+
- Remove `koffi.handle()` long replaced with `koffi.opaque()`
|
|
33
|
+
|
|
34
|
+
Consult the [migration guide](migration) for more information.
|
|
35
|
+
|
|
6
36
|
## Koffi 2
|
|
7
37
|
|
|
8
38
|
### Koffi 2.16
|
package/LICENSE.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (C)
|
|
3
|
+
Copyright (C) 2026 Niels Martignène <niels.martignene@protonmail.com>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
6
|
this software and associated documentation files (the “Software”), to deal in
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/{build.cjs → cnoke.cjs}
RENAMED
|
@@ -196,7 +196,7 @@ function compareVersions(ver1, ver2) {
|
|
|
196
196
|
|
|
197
197
|
// ../cnoke/src/assets.js
|
|
198
198
|
var FIND_CNOKE_CMAKE = `# SPDX-License-Identifier: MIT
|
|
199
|
-
# SPDX-FileCopyrightText:
|
|
199
|
+
# SPDX-FileCopyrightText: 2026 Niels Martign\xE8ne <niels.martignene@protonmail.com>
|
|
200
200
|
|
|
201
201
|
if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR
|
|
202
202
|
CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
|
|
@@ -324,7 +324,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU
|
|
|
324
324
|
endif()
|
|
325
325
|
`;
|
|
326
326
|
var WIN_DELAY_HOOK_C = `// SPDX-License-Identifier: MIT
|
|
327
|
-
// SPDX-FileCopyrightText:
|
|
327
|
+
// SPDX-FileCopyrightText: 2026 Niels Martign\xE8ne <niels.martignene@protonmail.com>
|
|
328
328
|
|
|
329
329
|
#include <stdlib.h>
|
|
330
330
|
#if !defined(NOMINMAX)
|
package/doc/callbacks.md
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
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.
|
|
6
6
|
|
|
7
7
|
```js
|
|
8
|
-
|
|
9
|
-
const koffi = require('koffi');
|
|
8
|
+
import koffi from 'koffi';
|
|
9
|
+
// CJS: const koffi = require('koffi');
|
|
10
10
|
|
|
11
11
|
// With the classic syntax, this callback expects an integer and returns nothing
|
|
12
12
|
const ExampleCallback = koffi.proto('ExampleCallback', 'void', ['int']);
|
|
@@ -71,8 +71,8 @@ int TransferToJS(const char *name, int age, int (*cb)(const char *str, int age))
|
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
```js
|
|
74
|
-
|
|
75
|
-
const koffi = require('koffi');
|
|
74
|
+
import koffi from 'koffi';
|
|
75
|
+
// CJS: const koffi = require('koffi');
|
|
76
76
|
|
|
77
77
|
const lib = koffi.load('./callbacks.so'); // Fake path
|
|
78
78
|
|
|
@@ -121,8 +121,8 @@ void SayIt(const char *name)
|
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
```js
|
|
124
|
-
|
|
125
|
-
const koffi = require('koffi');
|
|
124
|
+
import koffi from 'koffi';
|
|
125
|
+
// CJS: const koffi = require('koffi');
|
|
126
126
|
|
|
127
127
|
const lib = koffi.load('./callbacks.so'); // Fake path
|
|
128
128
|
|
|
@@ -162,15 +162,15 @@ let cb2 = koffi.register(store, store.get, 'IntCallback *'); // However in this
|
|
|
162
162
|
|
|
163
163
|
*New in Koffi 2.2, changed in Koffi 2.3*
|
|
164
164
|
|
|
165
|
-
Koffi does not have enough information to convert callback pointer arguments to an appropriate JS value. In this case, your JS function will receive
|
|
165
|
+
Koffi does not have enough information to convert callback pointer arguments to an appropriate JS value. In this case, your JS function will receive a *BigInt* value with the pointer address.
|
|
166
166
|
|
|
167
167
|
You can pass this value through to another C function that expects a pointer of the same type, or you can use [koffi.decode()](variables#decode-to-js-values) function to decode pointer arguments.
|
|
168
168
|
|
|
169
169
|
The following examples uses it to sort an array of strings in-place with the standard C function `qsort()`:
|
|
170
170
|
|
|
171
171
|
```js
|
|
172
|
-
|
|
173
|
-
const koffi = require('koffi');
|
|
172
|
+
import koffi from 'koffi';
|
|
173
|
+
// CJS: const koffi = require('koffi');
|
|
174
174
|
|
|
175
175
|
const lib = koffi.load('libc.so.6');
|
|
176
176
|
|
package/doc/contribute.md
CHANGED
|
@@ -151,7 +151,7 @@ cd ../../bin/koffi/packages
|
|
|
151
151
|
./publish.sh
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
-
Some platforms are emulated so this can take a few minutes until the pre-built binaries are ready.
|
|
154
|
+
Some platforms are emulated so this can take a few minutes until the pre-built binaries are ready. You might want to go grab a cup of coffee :)
|
|
155
155
|
|
|
156
156
|
# Code style
|
|
157
157
|
|
package/doc/functions.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
To declare functions, start by loading the shared library with `koffi.load(filename)`.
|
|
4
4
|
|
|
5
5
|
```js
|
|
6
|
-
|
|
7
|
-
const koffi = require('koffi');
|
|
6
|
+
import koffi from 'koffi';
|
|
7
|
+
// CJS: const koffi = require('koffi');
|
|
8
8
|
|
|
9
9
|
const lib = koffi.load('/path/to/shared/library'); // File extension depends on platforms: .so, .dll, .dylib, etc.
|
|
10
10
|
```
|
|
@@ -105,8 +105,8 @@ You can safely use these on non-x86 platforms, they are simply ignored.
|
|
|
105
105
|
Below you can find a small example showing how to use a non-default calling convention, with the two syntaxes:
|
|
106
106
|
|
|
107
107
|
```js
|
|
108
|
-
|
|
109
|
-
const koffi = require('koffi');
|
|
108
|
+
import koffi from 'koffi';
|
|
109
|
+
// CJS: const koffi = require('koffi');
|
|
110
110
|
|
|
111
111
|
const lib = koffi.load('user32.dll');
|
|
112
112
|
|
|
@@ -142,8 +142,8 @@ printf('Integer %d, double %g, str %s', 'int', 6, 'double', 8.5, 'str', 'THE END
|
|
|
142
142
|
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.
|
|
143
143
|
|
|
144
144
|
```js
|
|
145
|
-
|
|
146
|
-
const koffi = require('koffi');
|
|
145
|
+
import koffi from 'koffi';
|
|
146
|
+
// CJS: const koffi = require('koffi');
|
|
147
147
|
|
|
148
148
|
const lib = koffi.load('libc.so.6');
|
|
149
149
|
|
package/doc/input.md
CHANGED
|
@@ -278,8 +278,8 @@ const char *ConcatBuild(Concat *c)
|
|
|
278
278
|
```
|
|
279
279
|
|
|
280
280
|
```js
|
|
281
|
-
|
|
282
|
-
const koffi = require('koffi');
|
|
281
|
+
import koffi from 'koffi';
|
|
282
|
+
// CJS: const koffi = require('koffi');
|
|
283
283
|
|
|
284
284
|
const lib = koffi.load('./handles.so');
|
|
285
285
|
|
|
@@ -348,8 +348,8 @@ Koffi applies the following conversion rules when passing arrays to/from C:
|
|
|
348
348
|
See the example below:
|
|
349
349
|
|
|
350
350
|
```js
|
|
351
|
-
|
|
352
|
-
const koffi = require('koffi');
|
|
351
|
+
import koffi from 'koffi';
|
|
352
|
+
// CJS: const koffi = require('koffi');
|
|
353
353
|
|
|
354
354
|
// Those two structs are exactly the same, only the array conversion hint is different
|
|
355
355
|
const Foo1 = koffi.struct('Foo1', {
|
|
@@ -438,8 +438,8 @@ void AppendValues(struct FlexibleArray *arr, size_t count, int start, int step)
|
|
|
438
438
|
```
|
|
439
439
|
|
|
440
440
|
```js
|
|
441
|
-
|
|
442
|
-
const koffi = require('koffi');
|
|
441
|
+
import koffi from 'koffi';
|
|
442
|
+
// CJS: const koffi = require('koffi');
|
|
443
443
|
|
|
444
444
|
const lib = koffi.load('./flexible.so');
|
|
445
445
|
|
|
@@ -466,6 +466,70 @@ console.log(array); // Prints { count: 8, numbers: [1, 2, 3, 4, 5, 10, 12, 14] }
|
|
|
466
466
|
|
|
467
467
|
In C, dynamically-sized arrays are usually passed around as pointers. Read more about [array pointers](pointers#dynamic-arrays) in the relevant section.
|
|
468
468
|
|
|
469
|
+
# Enum types
|
|
470
|
+
|
|
471
|
+
*Added in Koffi 3.0*
|
|
472
|
+
|
|
473
|
+
C enumeration values are stored as integers. The underlying integer type is implementation-defined but Koffi tries to match usual platform behavior.
|
|
474
|
+
|
|
475
|
+
On POSIX platforms, Koffi follows the following rules:
|
|
476
|
+
|
|
477
|
+
- If no negative value exists: `unsigned int` by default, `uint64_t` if needed
|
|
478
|
+
- If any negative value exists: `int` by default, `int64_t` if needed
|
|
479
|
+
|
|
480
|
+
On Windows, things are simpler, and `int` is used all the time. Koffi will throw an error if any enumeration value does not fit in a 32-bit integer.
|
|
481
|
+
|
|
482
|
+
```js
|
|
483
|
+
// For OpenResult, the underlying type will be unsigned int on POSIX, int on Windows
|
|
484
|
+
const OpenResult = koffi.enumeration('OpenResult', {
|
|
485
|
+
Success: 0,
|
|
486
|
+
MissingFile: 1,
|
|
487
|
+
AccessDenied: 2,
|
|
488
|
+
OtherError: 3
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
// For RelativePosition, the underlying type will be int everywhere
|
|
492
|
+
const RelativePosition = koffi.enumeration('RelativePosition', {
|
|
493
|
+
Left: -1,
|
|
494
|
+
Center: 0,
|
|
495
|
+
Right: 1
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
// For IntLimits, the underlying type will be int64_t on POSIX, and fail on Windows
|
|
499
|
+
const Int64Limits = koffi.enumeration('Int64Limits', {
|
|
500
|
+
Min: -9223372036854775808n,
|
|
501
|
+
Max: 9223372036854775807n
|
|
502
|
+
});
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
```{warning}
|
|
506
|
+
This behavior may not match your compiler:
|
|
507
|
+
|
|
508
|
+
- POSIX platforms: GCC and Clang support will use a short integer type if `-fshort-enums` is specified and the enumeration values fit in `short` or `unsigned short`
|
|
509
|
+
- Windows: MSVC (and Clang) always use `int` even if some values do not fit, which matches what Koffi does... unless the compiler flag `/Zc:enumTypes` is set, maybe.
|
|
510
|
+
|
|
511
|
+
Use an explicit type specifier to work around these problems, as shown below.
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
You can access the constants in `values` member of the type object.
|
|
515
|
+
|
|
516
|
+
```js
|
|
517
|
+
console.log(OpenResult.values.MissingFile); // Prints 1
|
|
518
|
+
console.log(RelativePosition.values.Left); // Prints -1
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
You can specify the storage type explicitly as the last argument to `koffi.enumeration(name, values, type)`.
|
|
522
|
+
|
|
523
|
+
```js
|
|
524
|
+
// This one explictly uses int64_t as the underlying type,
|
|
525
|
+
// despite the fact that the values fit inside an int.
|
|
526
|
+
const ExplicitEnum = koffi.enumeration('ExplicitEnum', {
|
|
527
|
+
Zero: 0,
|
|
528
|
+
One: 1,
|
|
529
|
+
Two: 2
|
|
530
|
+
}, 'int64_t');
|
|
531
|
+
```
|
|
532
|
+
|
|
469
533
|
# Union types
|
|
470
534
|
|
|
471
535
|
The declaration and use of [union types](unions) will be explained in a later section, they are only briefly mentioned here if you need them.
|
package/doc/misc.md
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
# Types
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Type specifiers
|
|
4
4
|
|
|
5
|
-
*
|
|
5
|
+
*Changed in Koffi 3.0*
|
|
6
6
|
|
|
7
7
|
> [!NOTE]
|
|
8
|
-
>
|
|
9
|
-
>
|
|
10
|
-
> 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.
|
|
11
|
-
>
|
|
12
|
-
> Starting in Koffi 2.2, each record member is exposed as an object containing the name, the type and the offset within the record.
|
|
8
|
+
> In Koffi 2.0, types were External values, you had to use `koffi.introspect()` to get type information. In Koffi 3.0, this information is directly available in type objects, and this function is deprecated.
|
|
13
9
|
>
|
|
14
10
|
> Consult the [migration guide](migration) for more information.
|
|
15
11
|
|
|
16
|
-
|
|
12
|
+
You can use strings or type objects to give type information to Koffi (when declaring functions, structs, and so on). Use `koffi.type(spec)` to resolve all accepted type values (strings and type objects) to type objects.
|
|
13
|
+
|
|
14
|
+
You can inspect the type object for information: name, primitive, size, alignment, members (record types), reference type (array, pointer), length (array), arguments and return type (prototypes).
|
|
17
15
|
|
|
18
16
|
```js
|
|
19
17
|
const FoobarType = koffi.struct('FoobarType', {
|
|
@@ -22,7 +20,7 @@ const FoobarType = koffi.struct('FoobarType', {
|
|
|
22
20
|
c: 'double'
|
|
23
21
|
});
|
|
24
22
|
|
|
25
|
-
console.log(
|
|
23
|
+
console.log(FoobarType);
|
|
26
24
|
|
|
27
25
|
// Expected result on 64-bit machines:
|
|
28
26
|
// {
|
|
@@ -30,10 +28,11 @@ console.log(koffi.introspect(FoobarType));
|
|
|
30
28
|
// primitive: 'Record',
|
|
31
29
|
// size: 24,
|
|
32
30
|
// alignment: 8,
|
|
31
|
+
// disposable: false,
|
|
33
32
|
// members: {
|
|
34
|
-
// a: { name: 'a', type: [
|
|
35
|
-
// b: { name: 'b', type: [
|
|
36
|
-
// c: { name: 'c', type: [
|
|
33
|
+
// a: { name: 'a', type: [Type], offset: 0 },
|
|
34
|
+
// b: { name: 'b', type: [Type], offset: 8 },
|
|
35
|
+
// c: { name: 'c', type: [Type], offset: 16 }
|
|
37
36
|
// }
|
|
38
37
|
// }
|
|
39
38
|
```
|
|
@@ -43,7 +42,7 @@ Koffi also exposes a few more utility functions to get a subset of this informat
|
|
|
43
42
|
- `koffi.sizeof(type)` to get the size of a type
|
|
44
43
|
- `koffi.alignof(type)` to get the alignment of a type
|
|
45
44
|
- `koffi.offsetof(type, member_name)` to get the offset of a record member
|
|
46
|
-
- `koffi.
|
|
45
|
+
- `koffi.type(type)` to get the resolved type object from a type string
|
|
47
46
|
|
|
48
47
|
Just like before, you can refer to primitive types by their name or through `koffi.types`:
|
|
49
48
|
|
|
@@ -152,8 +151,8 @@ The standard POSIX error codes are available in `koffi.os.errno`, as shown below
|
|
|
152
151
|
```js
|
|
153
152
|
const assert = require('assert');
|
|
154
153
|
|
|
155
|
-
|
|
156
|
-
const koffi = require('koffi');
|
|
154
|
+
import koffi from 'koffi';
|
|
155
|
+
// CJS: const koffi = require('koffi');
|
|
157
156
|
|
|
158
157
|
const lib = koffi.load('libc.so.6');
|
|
159
158
|
|
package/doc/output.md
CHANGED
|
@@ -29,8 +29,8 @@ The same can be done when declaring a function with a C-like prototype string, w
|
|
|
29
29
|
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.
|
|
30
30
|
|
|
31
31
|
```js
|
|
32
|
-
|
|
33
|
-
const koffi = require('koffi');
|
|
32
|
+
import koffi from 'koffi';
|
|
33
|
+
// CJS: const koffi = require('koffi');
|
|
34
34
|
|
|
35
35
|
const user32 = koffi.load('user32.dll');
|
|
36
36
|
|
|
@@ -87,8 +87,8 @@ for (let hwnd = null;;) {
|
|
|
87
87
|
This example calls the POSIX function `gettimeofday()`, and uses the prototype-like syntax.
|
|
88
88
|
|
|
89
89
|
```js
|
|
90
|
-
|
|
91
|
-
const koffi = require('koffi');
|
|
90
|
+
import koffi from 'koffi';
|
|
91
|
+
// CJS: const koffi = require('koffi');
|
|
92
92
|
|
|
93
93
|
const lib = koffi.load('libc.so.6');
|
|
94
94
|
|
|
@@ -115,8 +115,8 @@ console.log(tv);
|
|
|
115
115
|
Many Win32 functions that use struct outputs require you to set a size member (often named `cbSize`). These functions won't work with `_Out_` because the size value must be copied from JS to C, use `_Inout_` in this case.
|
|
116
116
|
|
|
117
117
|
```js
|
|
118
|
-
|
|
119
|
-
const koffi = require('koffi');
|
|
118
|
+
import koffi from 'koffi';
|
|
119
|
+
// CJS: const koffi = require('koffi');
|
|
120
120
|
|
|
121
121
|
const user32 = koffi.load('user32.dll');
|
|
122
122
|
|
|
@@ -137,8 +137,8 @@ console.log(success, info);
|
|
|
137
137
|
This example opens an in-memory SQLite database, and uses the node-ffi-style function declaration syntax.
|
|
138
138
|
|
|
139
139
|
```js
|
|
140
|
-
|
|
141
|
-
const koffi = require('koffi');
|
|
140
|
+
import koffi from 'koffi';
|
|
141
|
+
// CJS: const koffi = require('koffi');
|
|
142
142
|
|
|
143
143
|
const lib = koffi.load('sqlite3.so');
|
|
144
144
|
|
|
@@ -215,8 +215,8 @@ You can use buffers and typed arrays for output (and input/output) pointer param
|
|
|
215
215
|
Once the native function returns, you can decode the content with `koffi.decode(value, type)` as in the following example:
|
|
216
216
|
|
|
217
217
|
```js
|
|
218
|
-
|
|
219
|
-
const koffi = require('koffi');
|
|
218
|
+
import koffi from 'koffi';
|
|
219
|
+
// CJS: const koffi = require('koffi');
|
|
220
220
|
|
|
221
221
|
const lib = koffi.load('libc.so.6');
|
|
222
222
|
|
package/doc/packaging.md
CHANGED
|
@@ -45,7 +45,7 @@ MyApp.exe
|
|
|
45
45
|
|
|
46
46
|
Some bundlers (such as vite) don't like when require is used with native modules.
|
|
47
47
|
|
|
48
|
-
In this case, you can use `
|
|
48
|
+
In this case, you can use `import koffi from 'koffi/indirect'` but you will need to make sure that the native Koffi modules are packaged properly.
|
|
49
49
|
|
|
50
50
|
# Packaging examples
|
|
51
51
|
|
|
@@ -53,7 +53,7 @@ In this case, you can use `require('koffi/indirect')` but you will need to make
|
|
|
53
53
|
|
|
54
54
|
Packaging with electron-builder should work as-is.
|
|
55
55
|
|
|
56
|
-
Take a look at the full [working example in the repository](https://codeberg.org/Koromix/rygel/src/branch/master/src/koffi/examples/electron-builder).
|
|
56
|
+
Take a look at the full [working example in the repository](https://codeberg.org/Koromix/rygel/src/branch/master/src/koffi/examples/packaging/electron-builder).
|
|
57
57
|
|
|
58
58
|
## Electron Forge
|
|
59
59
|
|
|
@@ -63,13 +63,13 @@ Packaging with Electron Force should work as-is, even when using webpack as conf
|
|
|
63
63
|
npm init electron-app@latest my-app -- --template=webpack
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
Take a look at the full [working example in the repository](https://codeberg.org/Koromix/rygel/src/branch/master/src/koffi/examples/electron-forge).
|
|
66
|
+
Take a look at the full [working example in the repository](https://codeberg.org/Koromix/rygel/src/branch/master/src/koffi/examples/packaging/electron-forge).
|
|
67
67
|
|
|
68
68
|
## NW.js
|
|
69
69
|
|
|
70
70
|
Packagers such as nw-builder should work as-is.
|
|
71
71
|
|
|
72
|
-
You can find a full [working example in the repository](https://codeberg.org/Koromix/rygel/src/branch/master/src/koffi/examples/nwjs).
|
|
72
|
+
You can find a full [working example in the repository](https://codeberg.org/Koromix/rygel/src/branch/master/src/koffi/examples/packaging/nwjs).
|
|
73
73
|
|
|
74
74
|
## Node.js and esbuild
|
|
75
75
|
|
|
@@ -79,10 +79,10 @@ You can easily tell esbuild to copy the native files with the copy loader and th
|
|
|
79
79
|
esbuild index.js --platform=node --bundle --loader:.node=copy --outdir=dist/
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
You can find a full [working example in the repository](https://codeberg.org/Koromix/rygel/src/branch/master/src/koffi/examples/node-esbuild).
|
|
82
|
+
You can find a full [working example in the repository](https://codeberg.org/Koromix/rygel/src/branch/master/src/koffi/examples/packaging/node-esbuild).
|
|
83
83
|
|
|
84
84
|
## Node.js and yao-pkg
|
|
85
85
|
|
|
86
86
|
Use [yao-pkg](https://github.com/yao-pkg/pkg) to make binary packages of your Node.js-based project.
|
|
87
87
|
|
|
88
|
-
You can find a full [working example in the repository](https://codeberg.org/Koromix/rygel/src/branch/master/src/koffi/examples/yao-pkg).
|
|
88
|
+
You can find a full [working example in the repository](https://codeberg.org/Koromix/rygel/src/branch/master/src/koffi/examples/packaging/yao-pkg).
|
package/doc/pointers.md
CHANGED
|
@@ -14,8 +14,8 @@ In C, pointer arguments are used for differenty purposes. It is important to dis
|
|
|
14
14
|
The following Win32 example uses `GetCursorPos()` (with an output parameter) to retrieve and show the current cursor position.
|
|
15
15
|
|
|
16
16
|
```js
|
|
17
|
-
|
|
18
|
-
const koffi = require('koffi');
|
|
17
|
+
import koffi from 'koffi';
|
|
18
|
+
// CJS: const koffi = require('koffi');
|
|
19
19
|
|
|
20
20
|
const lib = koffi.load('user32.dll');
|
|
21
21
|
|
|
@@ -49,6 +49,8 @@ const GetHandleInformation = lib.func('bool __stdcall GetHandleInformation(HANDL
|
|
|
49
49
|
const CloseHandle = lib.func('bool __stdcall CloseHandle(HANDLE h)');
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
Koffi uses BigInt numbers to represent opaque pointers.
|
|
53
|
+
|
|
52
54
|
## Pointer to primitive types
|
|
53
55
|
|
|
54
56
|
In javascript, it is not possible to pass a primitive value by reference to another function. This means that you cannot call a function and expect it to modify the value of one of its number or string parameter.
|
|
@@ -115,8 +117,8 @@ int64_t ComputeTotalLength(const char **strings)
|
|
|
115
117
|
```
|
|
116
118
|
|
|
117
119
|
```js
|
|
118
|
-
|
|
119
|
-
const koffi = require('koffi');
|
|
120
|
+
import koffi from 'koffi';
|
|
121
|
+
// CJS: const koffi = require('koffi');
|
|
120
122
|
|
|
121
123
|
const lib = koffi.load('./length.so');
|
|
122
124
|
|
|
@@ -144,8 +146,8 @@ Koffi provides two features to deal with this:
|
|
|
144
146
|
The example below shows the use of `koffi.as()` to read the header of a PNG file with `fread()` directly to a JS object.
|
|
145
147
|
|
|
146
148
|
```js
|
|
147
|
-
|
|
148
|
-
const koffi = require('koffi');
|
|
149
|
+
import koffi from 'koffi';
|
|
150
|
+
// CJS: const koffi = require('koffi');
|
|
149
151
|
|
|
150
152
|
const lib = koffi.load('libc.so.6');
|
|
151
153
|
|
|
@@ -216,8 +218,8 @@ const ExplicitFree = koffi.disposable('HeapStr16', 'str16', koffi.free); // You
|
|
|
216
218
|
The following example illustrates the use of a disposable type derived from *str*.
|
|
217
219
|
|
|
218
220
|
```js
|
|
219
|
-
|
|
220
|
-
const koffi = require('koffi');
|
|
221
|
+
import koffi from 'koffi';
|
|
222
|
+
// CJS: const koffi = require('koffi');
|
|
221
223
|
|
|
222
224
|
const lib = koffi.load('libc.so.6');
|
|
223
225
|
|
|
@@ -231,8 +233,8 @@ console.log(copy); // Prints Hello!
|
|
|
231
233
|
When you declare functions with the [prototype-like syntax](functions#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)`.
|
|
232
234
|
|
|
233
235
|
```js
|
|
234
|
-
|
|
235
|
-
const koffi = require('koffi');
|
|
236
|
+
import koffi from 'koffi';
|
|
237
|
+
// CJS: const koffi = require('koffi');
|
|
236
238
|
|
|
237
239
|
const lib = koffi.load('libc.so.6');
|
|
238
240
|
|
|
@@ -260,8 +262,8 @@ You can access unmanaged memory with `koffi.view(ptr, len)`. This function takes
|
|
|
260
262
|
The following Linux example writes the string "Hello World!" to a file named "hello.txt" through mmaped memory, to demontrate the use of `koffi.view()`:
|
|
261
263
|
|
|
262
264
|
```js
|
|
263
|
-
|
|
264
|
-
const koffi = require('koffi');
|
|
265
|
+
import koffi from 'koffi';
|
|
266
|
+
// CJS: const koffi = require('koffi');
|
|
265
267
|
|
|
266
268
|
const libc = koffi.load('libc.so.6');
|
|
267
269
|
|
|
@@ -322,7 +324,3 @@ function write(filename, str) {
|
|
|
322
324
|
}
|
|
323
325
|
}
|
|
324
326
|
```
|
|
325
|
-
|
|
326
|
-
# Unwrap pointers
|
|
327
|
-
|
|
328
|
-
You can use `koffi.address(ptr)` on a pointer to get the numeric value as a [BigInt object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt).
|
package/doc/start.md
CHANGED
|
@@ -30,8 +30,8 @@ This is a small example for Linux systems, which uses `gettimeofday()`, `localti
|
|
|
30
30
|
It illustrates the use of output parameters.
|
|
31
31
|
|
|
32
32
|
```js
|
|
33
|
-
|
|
34
|
-
const koffi = require('koffi');
|
|
33
|
+
import koffi from 'koffi';
|
|
34
|
+
// CJS: const koffi = require('koffi');
|
|
35
35
|
|
|
36
36
|
// Load the shared library
|
|
37
37
|
const lib = koffi.load('libc.so.6');
|
|
@@ -81,8 +81,8 @@ This is a small example targeting the Win32 API, using `MessageBox()` to show a
|
|
|
81
81
|
It illustrates the use of the x86 stdcall calling convention, and the use of UTF-8 and UTF-16 string arguments.
|
|
82
82
|
|
|
83
83
|
```js
|
|
84
|
-
|
|
85
|
-
const koffi = require('koffi');
|
|
84
|
+
import koffi from 'koffi';
|
|
85
|
+
// CJS: const koffi = require('koffi');
|
|
86
86
|
|
|
87
87
|
// Load the shared library
|
|
88
88
|
const lib = koffi.load('user32.dll');
|
package/doc/unions.md
CHANGED
|
@@ -56,8 +56,8 @@ DoSomething('string', { str: 'Hello!' });
|
|
|
56
56
|
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).
|
|
57
57
|
|
|
58
58
|
```js
|
|
59
|
-
|
|
60
|
-
const koffi = require('koffi');
|
|
59
|
+
import koffi from 'koffi';
|
|
60
|
+
// CJS: const koffi = require('koffi');
|
|
61
61
|
|
|
62
62
|
// Win32 type and functions
|
|
63
63
|
|
package/doc/variables.md
CHANGED
|
@@ -23,7 +23,7 @@ You cannot directly manipulate these variables, use:
|
|
|
23
23
|
|
|
24
24
|
*New in Koffi 2.2, changed in Koffi 2.3*
|
|
25
25
|
|
|
26
|
-
Use `koffi.decode()` to decode C pointers,
|
|
26
|
+
Use `koffi.decode()` to decode C pointers, represented by BigInt numbers.
|
|
27
27
|
|
|
28
28
|
Some arguments are optional and this function can be called in several ways:
|
|
29
29
|
|
|
@@ -66,12 +66,12 @@ console.log(koffi.decode(my_string, 'const char *', 3)) // Prints "foo"
|
|
|
66
66
|
|
|
67
67
|
*New in Koffi 2.6*
|
|
68
68
|
|
|
69
|
-
Use `koffi.encode()` to encode JS values into C symbols or pointers,
|
|
69
|
+
Use `koffi.encode()` to encode JS values into C symbols or pointers, which are represented by BigInt numbers.
|
|
70
70
|
|
|
71
71
|
Some arguments are optional and this function can be called in several ways:
|
|
72
72
|
|
|
73
|
-
- `koffi.encode(
|
|
74
|
-
- `koffi.encode(
|
|
73
|
+
- `koffi.encode(ptr, type, value)`: no offset
|
|
74
|
+
- `koffi.encode(ptr, offset, type, value)`: explicit offset to add to the pointer before encoding
|
|
75
75
|
|
|
76
76
|
We'll reuse the examples shown above and change the variable values with `koffi.encode()`.
|
|
77
77
|
|