koffi 1.3.4 → 1.3.5
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/CMakeLists.txt +1 -1
- package/ChangeLog.md +13 -1
- package/build/qemu/1.3.5/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_win32_x64.tar.gz +0 -0
- package/doc/dist/doctrees/changes.doctree +0 -0
- package/doc/dist/doctrees/environment.pickle +0 -0
- package/doc/dist/doctrees/functions.doctree +0 -0
- package/doc/dist/doctrees/index.doctree +0 -0
- package/doc/dist/doctrees/memory.doctree +0 -0
- package/doc/dist/doctrees/start.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/dist/html/_sources/functions.md.txt +16 -14
- package/doc/dist/html/_sources/memory.md.txt +6 -3
- package/doc/dist/html/_sources/start.md.txt +3 -3
- package/doc/dist/html/_sources/types.md.txt +10 -8
- package/doc/dist/html/changes.html +15 -1
- package/doc/dist/html/functions.html +16 -19
- package/doc/dist/html/index.html +4 -2
- package/doc/dist/html/memory.html +8 -3
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +1 -1
- package/doc/dist/html/searchindex.js +1 -1
- package/doc/dist/html/start.html +3 -3
- package/doc/dist/html/types.html +9 -8
- package/doc/functions.md +16 -14
- package/doc/memory.md +6 -3
- package/doc/start.md +3 -3
- package/doc/types.md +10 -8
- package/package.json +2 -2
- package/qemu/registry/machines.json +6 -11
- package/src/abi_x86.cc +0 -5
- package/src/call.cc +2 -1
- package/src/ffi.cc +71 -22
- package/src/ffi.hh +11 -4
- package/test/async.js +1 -1
- package/build/qemu/1.3.4/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.4/koffi_win32_x64.tar.gz +0 -0
package/CMakeLists.txt
CHANGED
|
@@ -54,7 +54,7 @@ set(KOFFI_SRC
|
|
|
54
54
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
55
55
|
# CMAKE_SYSTEM_PROCESSOR is wrong on Windows ARM64
|
|
56
56
|
|
|
57
|
-
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch|arm" OR CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
|
|
57
|
+
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch|arm" OR CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64" OR CMAKE_OSX_ARCHITECTURES MATCHES "arm")
|
|
58
58
|
if(WIN32)
|
|
59
59
|
get_filename_component(cl_dir "${CMAKE_CXX_COMPILER}" DIRECTORY)
|
|
60
60
|
file(TO_CMAKE_PATH "${cl_dir}/armasm64.exe" asm_compiler)
|
package/ChangeLog.md
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Koffi 1.3.5
|
|
4
|
+
|
|
5
|
+
**Main changes:**
|
|
6
|
+
|
|
7
|
+
- Fix memory leak when many async calls are running
|
|
8
|
+
- Add configurable limit for maximum number of async calls (max_async_calls)
|
|
9
|
+
|
|
10
|
+
**Other changes:**
|
|
11
|
+
|
|
12
|
+
- Reduce default async memory stack and heap size
|
|
13
|
+
- Various documentation improvements
|
|
14
|
+
|
|
3
15
|
## Koffi 1.3.4
|
|
4
16
|
|
|
5
17
|
**Main fixes:**
|
|
6
18
|
|
|
7
|
-
- Fix possible OpenBSD i386 crash with (void) functions
|
|
19
|
+
- Fix possible OpenBSD i386 crash with `(void)` functions
|
|
8
20
|
|
|
9
21
|
## Koffi 1.3.3
|
|
10
22
|
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Function definitions
|
|
4
4
|
|
|
5
|
-
To declare functions, start by loading the shared library with `koffi.load()`.
|
|
5
|
+
To declare functions, start by loading the shared library with `koffi.load(filename)`.
|
|
6
6
|
|
|
7
7
|
```js
|
|
8
8
|
const koffi = require('koffi');
|
|
9
9
|
const lib = koffi.load('/path/to/shared/library'); // File extension depends on platforms: .so, .dll, .dylib, etc.
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
You can use the returned object to load C functions from the library.
|
|
12
|
+
You can use the returned object to load C functions from the library. To do so, you can use two syntaxes:
|
|
13
13
|
|
|
14
|
-
-
|
|
14
|
+
- The classic syntax, inspired by node-ffi
|
|
15
15
|
- C-like prototypes
|
|
16
16
|
|
|
17
17
|
### Classic syntax
|
|
@@ -27,18 +27,20 @@ Koffi automatically tries mangled names for non-standard x86 calling conventions
|
|
|
27
27
|
|
|
28
28
|
### C-like prototypes
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
If you prefer, you can declare functions using simple C-like prototype strings, as shown below:
|
|
31
31
|
|
|
32
32
|
```js
|
|
33
33
|
const printf = lib.func('int printf(const char *fmt, ...)');
|
|
34
34
|
const atoi = lib.func('int atoi(string)'); // The parameter name is not used by Koffi, and optional
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
You can use `()` or `(void)` for functions that take no argument.
|
|
38
|
+
|
|
37
39
|
## Synchronous calls
|
|
38
40
|
|
|
39
41
|
By default, calling a C function happens synchronously.
|
|
40
42
|
|
|
41
|
-
Most architectures only support one procedure call standard per process. The 32-bit x86 platform is an exception to this, and Koffi
|
|
43
|
+
Most architectures only support one procedure call standard per process. The 32-bit x86 platform is an exception to this, and Koffi supports several x86 conventions:
|
|
42
44
|
|
|
43
45
|
Convention | Classic form | Prototype form | Description
|
|
44
46
|
------------- | ----------------------------- | -------------- | -------------------------------------------------------------------
|
|
@@ -49,7 +51,7 @@ Most architectures only support one procedure call standard per process. The 32-
|
|
|
49
51
|
|
|
50
52
|
You can safely use these on non-x86 platforms, they are simply ignored.
|
|
51
53
|
|
|
52
|
-
Below you can find a small example showing how to use a non-default calling convention:
|
|
54
|
+
Below you can find a small example showing how to use a non-default calling convention, with the two syntaxes:
|
|
53
55
|
|
|
54
56
|
```js
|
|
55
57
|
const koffi = require('koffi');
|
|
@@ -75,7 +77,9 @@ atoi.async('1257', (err, res) => {
|
|
|
75
77
|
})
|
|
76
78
|
console.log('Hello World!');
|
|
77
79
|
|
|
78
|
-
// This program will print
|
|
80
|
+
// This program will print:
|
|
81
|
+
// Hello World!
|
|
82
|
+
// Result: 1257
|
|
79
83
|
```
|
|
80
84
|
|
|
81
85
|
These calls are executed by worker threads. It is **your responsibility to deal with data sharing issues** in the native code that may be caused by multi-threading.
|
|
@@ -103,7 +107,7 @@ On x86 platforms, only the Cdecl convention can be used for variadic functions.
|
|
|
103
107
|
|
|
104
108
|
By default, Koffi will only forward arguments from Javascript to C. However, many C functions use pointer arguments for output values, or input/output values.
|
|
105
109
|
|
|
106
|
-
For
|
|
110
|
+
For simplicity, and because Javascript only has value semantics for primitive types, Koffi can marshal out (or in/out) two types of parameters:
|
|
107
111
|
|
|
108
112
|
- [Structs](types.md#struct-types) (to/from JS objects)
|
|
109
113
|
- [Opaque handles](types.md#opaque-handles)
|
|
@@ -168,8 +172,6 @@ sqlite3_close_v2(db);
|
|
|
168
172
|
|
|
169
173
|
## Javascript callbacks
|
|
170
174
|
|
|
171
|
-
### Using callbacks
|
|
172
|
-
|
|
173
175
|
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.
|
|
174
176
|
|
|
175
177
|
```js
|
|
@@ -182,7 +184,7 @@ const ExampleCallback = koffi.callback('ExampleCallback', 'void', ['int']);
|
|
|
182
184
|
const AddDoubleFloat = koffi.callback('double AddDoubleFloat(double d, float f)');
|
|
183
185
|
```
|
|
184
186
|
|
|
185
|
-
Once your callback type is declared, you can use
|
|
187
|
+
Once your callback type is declared, you can use it in struct definitions, or as function parameter and/or return type.
|
|
186
188
|
|
|
187
189
|
Here is a small example with the C part and the JS part.
|
|
188
190
|
|
|
@@ -219,8 +221,8 @@ console.log(ret);
|
|
|
219
221
|
|
|
220
222
|
On x86 platforms, only Cdecl and Stdcall callbacks are supported.
|
|
221
223
|
|
|
222
|
-
|
|
224
|
+
## Thread safety
|
|
223
225
|
|
|
224
|
-
|
|
226
|
+
Asynchronous functions run on worker threads. You need to deal with thread safety issues if you share data between threads.
|
|
225
227
|
|
|
226
|
-
|
|
228
|
+
Callbacks must be called from the main thread, or more precisely from the same thread as the V8 intepreter. Calling a callback from another thread is undefined behavior, and will likely lead to a crash or a big mess. You've been warned!
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
For synchronous/normal calls, Koffi uses two preallocated memory blocks:
|
|
6
6
|
|
|
7
|
-
- One to construct
|
|
7
|
+
- One to construct the C stack and assign registers, subsequently used by the platform-specific assembly code (1 MiB by default)
|
|
8
8
|
- One to allocate strings and big objects/structs (2 MiB by default)
|
|
9
9
|
|
|
10
10
|
Unless very big strings or objects (at least more than one page of memory) are used, no extra allocation ever happens during calls or callbacks.
|
|
@@ -18,12 +18,15 @@ console.log(config);
|
|
|
18
18
|
|
|
19
19
|
The same is true for asynchronous calls. When an asynchronous call is made, Koffi will allocate new blocks unless there is an unused (resident) set of blocks still available. Once the asynchronous call is finished, these blocks are freed if there are more than `resident_async_pools` sets of blocks left around.
|
|
20
20
|
|
|
21
|
+
There cannot be more than `max_async_calls` running at the same time.
|
|
22
|
+
|
|
21
23
|
## Default settings
|
|
22
24
|
|
|
23
25
|
Setting | Default | Description
|
|
24
26
|
-------------------- | ------- | -----------------------------------------------
|
|
25
27
|
sync_stack_size | 1 MiB | Stack size for synchronous calls
|
|
26
28
|
sync_heap_size | 2 MiB | Heap size for synchronous calls
|
|
27
|
-
async_stack_size |
|
|
28
|
-
async_heap_size |
|
|
29
|
+
async_stack_size | 256 kiB | Stack size for asynchronous calls
|
|
30
|
+
async_heap_size | 512 kiB | Heap size for asynchronous calls
|
|
29
31
|
resident_async_pools | 2 | Number of resident pools for asynchronous calls
|
|
32
|
+
max_async_calls | 64 | Maximum number of ongoing asynchronous calls
|
|
@@ -19,7 +19,7 @@ Below you can find three examples:
|
|
|
19
19
|
|
|
20
20
|
## Small Linux example
|
|
21
21
|
|
|
22
|
-
This is a small example for Linux systems, which uses `gettimeofday()` and `printf()` to print the current time
|
|
22
|
+
This is a small example for Linux systems, which uses `gettimeofday()`, `localtime_r()` and `printf()` to print the current time.
|
|
23
23
|
|
|
24
24
|
It illustrates the use of output parameters.
|
|
25
25
|
|
|
@@ -69,7 +69,7 @@ printf('Local time: %02d:%02d:%02d\n', 'int', now.tm_hour, 'int', now.tm_min, 'i
|
|
|
69
69
|
|
|
70
70
|
## Small Windows example
|
|
71
71
|
|
|
72
|
-
This is a small example targeting the Win32 API, using `MessageBox()` to show a Hello message to the user.
|
|
72
|
+
This is a small example targeting the Win32 API, using `MessageBox()` to show a *Hello World!* message to the user.
|
|
73
73
|
|
|
74
74
|
It illustrates the use of the x86 stdcall calling convention.
|
|
75
75
|
|
|
@@ -85,5 +85,5 @@ const MB_ICONINFORMATION = 0x40;
|
|
|
85
85
|
// Find functions
|
|
86
86
|
const MessageBoxA = lib.stdcall('MessageBoxA', 'int', ['void *', 'string', 'string', 'uint']);
|
|
87
87
|
|
|
88
|
-
MessageBoxA(null, 'Hello', '
|
|
88
|
+
MessageBoxA(null, 'Hello World!', 'Koffi', MB_ICONINFORMATION);
|
|
89
89
|
```
|
|
@@ -42,6 +42,8 @@ Number (float) | float64 | 8 | |
|
|
|
42
42
|
Number (float) | float | 4 | |
|
|
43
43
|
Number (float) | double | 8 | |
|
|
44
44
|
|
|
45
|
+
Koffi also accepts BigInt values when converting from JS to C integers. If the value exceeds the range of the C type, Koffi will convert the number to an undefined value. In the reverse direction, BigInt values are automatically used when needed for big 64-bit integers.
|
|
46
|
+
|
|
45
47
|
Koffi defines a few more types that can change size depending on the OS and the architecture:
|
|
46
48
|
|
|
47
49
|
JS type | C type | Signedness | Note
|
|
@@ -95,7 +97,7 @@ const A = koffi.struct('A', {
|
|
|
95
97
|
|
|
96
98
|
Koffi follows the C and ABI rules regarding struct alignment and padding.
|
|
97
99
|
|
|
98
|
-
Once a struct is declared, you can use it by name (with a string, like you can do for primitive types) or
|
|
100
|
+
Once a struct is declared, you can use it by name (with a string, like you can do for primitive types) or through the value returned by the call to `koffi.struct()`. Only the latter is possible when declaring an anonymous struct.
|
|
99
101
|
|
|
100
102
|
```js
|
|
101
103
|
// The following two function declarations are equivalent, and declare a function taking an A value and returning A
|
|
@@ -107,9 +109,9 @@ const Function2 = lib.func('Function', A, [A]);
|
|
|
107
109
|
|
|
108
110
|
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:
|
|
109
111
|
|
|
110
|
-
- **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
|
|
111
|
-
- **Opaque handles**: the library does not expose the contents of the structs, and only provides you with a pointer to it (e.g. `
|
|
112
|
-
- **Arrays**: in C, you dynamically-sized arrays are usually passed to functions with pointers, either NULL-terminated or with an additional length argument.
|
|
112
|
+
- **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).
|
|
113
|
+
- **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.
|
|
114
|
+
- **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.
|
|
113
115
|
- **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.
|
|
114
116
|
|
|
115
117
|
### Struct pointers
|
|
@@ -351,7 +353,7 @@ const ComputeTotalLength = lib.func('int64_t ComputeTotalLength(const char **str
|
|
|
351
353
|
let strings = ['Get', 'Total', 'Length', null];
|
|
352
354
|
let total = ComputeTotalLength(strings);
|
|
353
355
|
|
|
354
|
-
console.log(total); // Prints
|
|
356
|
+
console.log(total); // Prints 14
|
|
355
357
|
```
|
|
356
358
|
|
|
357
359
|
By default, just like for objects, array arguments are copied from JS to C but not vice-versa. You can however change the direction as documented in the section on [output parameters](functions.md#output-parameters).
|
|
@@ -423,7 +425,7 @@ console.log(filenames);
|
|
|
423
425
|
|
|
424
426
|
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.
|
|
425
427
|
|
|
426
|
-
However, arrays and objects (among others) are reference type values. Assigning an array or an object from one variable to another does not invole any copy. Instead, as the following example illustrates, the new variable references the same
|
|
428
|
+
However, arrays and objects (among others) are reference type values. Assigning an array or an object from one variable to another does not invole any copy. Instead, as the following example illustrates, the new variable references the same array as the first:
|
|
427
429
|
|
|
428
430
|
```js
|
|
429
431
|
let list1 = [1, 2];
|
|
@@ -436,7 +438,7 @@ console.log(list1); // Prints [1, 42]
|
|
|
436
438
|
|
|
437
439
|
All of this means that C functions that are expected to modify their primitive output values (such as an `int *` parameter) cannot be used directly. However, thanks to Koffi's transparent array support, you can use Javascript arrays to approximate reference semantics with single-element arrays.
|
|
438
440
|
|
|
439
|
-
Below, you can find an example of an addition function where the result is stored in an `int *` output parameter and how to use this function from Koffi.
|
|
441
|
+
Below, you can find an example of an addition function where the result is stored in an `int *` input/output parameter and how to use this function from Koffi.
|
|
440
442
|
|
|
441
443
|
```c
|
|
442
444
|
void AddInt(int *dest, int add)
|
|
@@ -445,7 +447,7 @@ void AddInt(int *dest, int add)
|
|
|
445
447
|
}
|
|
446
448
|
```
|
|
447
449
|
|
|
448
|
-
You can simply pass a single-element array as the
|
|
450
|
+
You can simply pass a single-element array as the first argument:
|
|
449
451
|
|
|
450
452
|
```js
|
|
451
453
|
const AddInt = lib.func('void AddInt(_Inout_ int *dest, int add)');
|
|
@@ -205,11 +205,24 @@
|
|
|
205
205
|
<article role="main">
|
|
206
206
|
<section id="changelog">
|
|
207
207
|
<h1>Changelog<a class="headerlink" href="#changelog" title="Permalink to this heading">#</a></h1>
|
|
208
|
+
<section id="koffi-1-3-5">
|
|
209
|
+
<h2>Koffi 1.3.5<a class="headerlink" href="#koffi-1-3-5" title="Permalink to this heading">#</a></h2>
|
|
210
|
+
<p><strong>Main changes:</strong></p>
|
|
211
|
+
<ul class="simple">
|
|
212
|
+
<li><p>Fix memory leak when many async calls are running</p></li>
|
|
213
|
+
<li><p>Add configurable limit for maximum number of async calls (max_async_calls)</p></li>
|
|
214
|
+
</ul>
|
|
215
|
+
<p><strong>Other changes:</strong></p>
|
|
216
|
+
<ul class="simple">
|
|
217
|
+
<li><p>Reduce default async memory stack and heap size</p></li>
|
|
218
|
+
<li><p>Various documentation improvements</p></li>
|
|
219
|
+
</ul>
|
|
220
|
+
</section>
|
|
208
221
|
<section id="koffi-1-3-4">
|
|
209
222
|
<h2>Koffi 1.3.4<a class="headerlink" href="#koffi-1-3-4" title="Permalink to this heading">#</a></h2>
|
|
210
223
|
<p><strong>Main fixes:</strong></p>
|
|
211
224
|
<ul class="simple">
|
|
212
|
-
<li><p>Fix possible OpenBSD i386 crash with (void) functions</p></li>
|
|
225
|
+
<li><p>Fix possible OpenBSD i386 crash with <code class="docutils literal notranslate"><span class="pre">(void)</span></code> functions</p></li>
|
|
213
226
|
</ul>
|
|
214
227
|
</section>
|
|
215
228
|
<section id="koffi-1-3-3">
|
|
@@ -348,6 +361,7 @@
|
|
|
348
361
|
<div class="toc-tree">
|
|
349
362
|
<ul>
|
|
350
363
|
<li><a class="reference internal" href="#">Changelog</a><ul>
|
|
364
|
+
<li><a class="reference internal" href="#koffi-1-3-5">Koffi 1.3.5</a></li>
|
|
351
365
|
<li><a class="reference internal" href="#koffi-1-3-4">Koffi 1.3.4</a></li>
|
|
352
366
|
<li><a class="reference internal" href="#koffi-1-3-3">Koffi 1.3.3</a></li>
|
|
353
367
|
<li><a class="reference internal" href="#koffi-1-3-2">Koffi 1.3.2</a></li>
|
|
@@ -207,14 +207,14 @@
|
|
|
207
207
|
<h1>Function calls<a class="headerlink" href="#function-calls" title="Permalink to this heading">#</a></h1>
|
|
208
208
|
<section id="function-definitions">
|
|
209
209
|
<h2>Function definitions<a class="headerlink" href="#function-definitions" title="Permalink to this heading">#</a></h2>
|
|
210
|
-
<p>To declare functions, start by loading the shared library with <code class="docutils literal notranslate"><span class="pre">koffi.load()</span></code>.</p>
|
|
210
|
+
<p>To declare functions, start by loading the shared library with <code class="docutils literal notranslate"><span class="pre">koffi.load(filename)</span></code>.</p>
|
|
211
211
|
<div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span><span class="w"> </span><span class="nx">koffi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">'koffi'</span><span class="p">);</span><span class="w"></span>
|
|
212
212
|
<span class="linenos">2</span><span class="kd">const</span><span class="w"> </span><span class="nx">lib</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">'/path/to/shared/library'</span><span class="p">);</span><span class="w"> </span><span class="c1">// File extension depends on platforms: .so, .dll, .dylib, etc.</span><span class="w"></span>
|
|
213
213
|
</pre></div>
|
|
214
214
|
</div>
|
|
215
|
-
<p>You can use the returned object to load C functions from the library.
|
|
215
|
+
<p>You can use the returned object to load C functions from the library. To do so, you can use two syntaxes:</p>
|
|
216
216
|
<ul class="simple">
|
|
217
|
-
<li><p>
|
|
217
|
+
<li><p>The classic syntax, inspired by node-ffi</p></li>
|
|
218
218
|
<li><p>C-like prototypes</p></li>
|
|
219
219
|
</ul>
|
|
220
220
|
<section id="classic-syntax">
|
|
@@ -228,17 +228,18 @@
|
|
|
228
228
|
</section>
|
|
229
229
|
<section id="c-like-prototypes">
|
|
230
230
|
<h3>C-like prototypes<a class="headerlink" href="#c-like-prototypes" title="Permalink to this heading">#</a></h3>
|
|
231
|
-
<p>
|
|
231
|
+
<p>If you prefer, you can declare functions using simple C-like prototype strings, as shown below:</p>
|
|
232
232
|
<div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span><span class="w"> </span><span class="nx">printf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">'int printf(const char *fmt, ...)'</span><span class="p">);</span><span class="w"></span>
|
|
233
233
|
<span class="linenos">2</span><span class="kd">const</span><span class="w"> </span><span class="nx">atoi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">lib</span><span class="p">.</span><span class="nx">func</span><span class="p">(</span><span class="s1">'int atoi(string)'</span><span class="p">);</span><span class="w"> </span><span class="c1">// The parameter name is not used by Koffi, and optional</span><span class="w"></span>
|
|
234
234
|
</pre></div>
|
|
235
235
|
</div>
|
|
236
|
+
<p>You can use <code class="docutils literal notranslate"><span class="pre">()</span></code> or <code class="docutils literal notranslate"><span class="pre">(void)</span></code> for functions that take no argument.</p>
|
|
236
237
|
</section>
|
|
237
238
|
</section>
|
|
238
239
|
<section id="synchronous-calls">
|
|
239
240
|
<h2>Synchronous calls<a class="headerlink" href="#synchronous-calls" title="Permalink to this heading">#</a></h2>
|
|
240
241
|
<p>By default, calling a C function happens synchronously.</p>
|
|
241
|
-
<p>Most architectures only support one procedure call standard per process. The 32-bit x86 platform is an exception to this, and Koffi
|
|
242
|
+
<p>Most architectures only support one procedure call standard per process. The 32-bit x86 platform is an exception to this, and Koffi supports several x86 conventions:</p>
|
|
242
243
|
<div class="table-wrapper colwidths-auto docutils container">
|
|
243
244
|
<table class="docutils align-default">
|
|
244
245
|
<thead>
|
|
@@ -273,7 +274,7 @@
|
|
|
273
274
|
</table>
|
|
274
275
|
</div>
|
|
275
276
|
<p>You can safely use these on non-x86 platforms, they are simply ignored.</p>
|
|
276
|
-
<p>Below you can find a small example showing how to use a non-default calling convention:</p>
|
|
277
|
+
<p>Below you can find a small example showing how to use a non-default calling convention, with the two syntaxes:</p>
|
|
277
278
|
<div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span><span class="w"> </span><span class="nx">koffi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">'koffi'</span><span class="p">);</span><span class="w"></span>
|
|
278
279
|
<span class="linenos">2</span><span class="kd">const</span><span class="w"> </span><span class="nx">lib</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">'user32.dll'</span><span class="p">);</span><span class="w"></span>
|
|
279
280
|
<span class="linenos">3</span>
|
|
@@ -296,7 +297,9 @@
|
|
|
296
297
|
<span class="linenos"> 8</span><span class="p">})</span><span class="w"></span>
|
|
297
298
|
<span class="linenos"> 9</span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Hello World!'</span><span class="p">);</span><span class="w"></span>
|
|
298
299
|
<span class="linenos">10</span>
|
|
299
|
-
<span class="linenos">11</span><span class="c1">// This program will print
|
|
300
|
+
<span class="linenos">11</span><span class="c1">// This program will print:</span><span class="w"></span>
|
|
301
|
+
<span class="linenos">12</span><span class="c1">// Hello World!</span><span class="w"></span>
|
|
302
|
+
<span class="linenos">13</span><span class="c1">// Result: 1257</span><span class="w"></span>
|
|
300
303
|
</pre></div>
|
|
301
304
|
</div>
|
|
302
305
|
<p>These calls are executed by worker threads. It is <strong>your responsibility to deal with data sharing issues</strong> in the native code that may be caused by multi-threading.</p>
|
|
@@ -318,7 +321,7 @@
|
|
|
318
321
|
<section id="output-parameters">
|
|
319
322
|
<h2>Output parameters<a class="headerlink" href="#output-parameters" title="Permalink to this heading">#</a></h2>
|
|
320
323
|
<p>By default, Koffi will only forward arguments from Javascript to C. However, many C functions use pointer arguments for output values, or input/output values.</p>
|
|
321
|
-
<p>For
|
|
324
|
+
<p>For simplicity, and because Javascript only has value semantics for primitive types, Koffi can marshal out (or in/out) two types of parameters:</p>
|
|
322
325
|
<ul class="simple">
|
|
323
326
|
<li><p><a class="reference internal" href="types#struct-types"><span class="std std-doc">Structs</span></a> (to/from JS objects)</p></li>
|
|
324
327
|
<li><p><a class="reference internal" href="types#opaque-handles"><span class="std std-doc">Opaque handles</span></a></p></li>
|
|
@@ -382,8 +385,6 @@
|
|
|
382
385
|
</section>
|
|
383
386
|
<section id="javascript-callbacks">
|
|
384
387
|
<h2>Javascript callbacks<a class="headerlink" href="#javascript-callbacks" title="Permalink to this heading">#</a></h2>
|
|
385
|
-
<section id="using-callbacks">
|
|
386
|
-
<h3>Using callbacks<a class="headerlink" href="#using-callbacks" title="Permalink to this heading">#</a></h3>
|
|
387
388
|
<p>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.</p>
|
|
388
389
|
<div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="kd">const</span><span class="w"> </span><span class="nx">koffi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">'koffi'</span><span class="p">);</span><span class="w"></span>
|
|
389
390
|
<span class="linenos">2</span>
|
|
@@ -394,7 +395,7 @@
|
|
|
394
395
|
<span class="linenos">7</span><span class="kd">const</span><span class="w"> </span><span class="nx">AddDoubleFloat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">koffi</span><span class="p">.</span><span class="nx">callback</span><span class="p">(</span><span class="s1">'double AddDoubleFloat(double d, float f)'</span><span class="p">);</span><span class="w"></span>
|
|
395
396
|
</pre></div>
|
|
396
397
|
</div>
|
|
397
|
-
<p>Once your callback type is declared, you can use
|
|
398
|
+
<p>Once your callback type is declared, you can use it in struct definitions, or as function parameter and/or return type.</p>
|
|
398
399
|
<p>Here is a small example with the C part and the JS part.</p>
|
|
399
400
|
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><string.h></span><span class="cp"></span>
|
|
400
401
|
<span class="linenos">2</span>
|
|
@@ -428,10 +429,9 @@
|
|
|
428
429
|
<p>On x86 platforms, only Cdecl and Stdcall callbacks are supported.</p>
|
|
429
430
|
</section>
|
|
430
431
|
<section id="thread-safety">
|
|
431
|
-
<
|
|
432
|
-
<p>
|
|
433
|
-
<p>
|
|
434
|
-
</section>
|
|
432
|
+
<h2>Thread safety<a class="headerlink" href="#thread-safety" title="Permalink to this heading">#</a></h2>
|
|
433
|
+
<p>Asynchronous functions run on worker threads. You need to deal with thread safety issues if you share data between threads.</p>
|
|
434
|
+
<p>Callbacks must be called from the main thread, or more precisely from the same thread as the V8 intepreter. Calling a callback from another thread is undefined behavior, and will likely lead to a crash or a big mess. You’ve been warned!</p>
|
|
435
435
|
</section>
|
|
436
436
|
</section>
|
|
437
437
|
|
|
@@ -506,13 +506,10 @@
|
|
|
506
506
|
<li><a class="reference internal" href="#opaque-handle-example">Opaque handle example</a></li>
|
|
507
507
|
</ul>
|
|
508
508
|
</li>
|
|
509
|
-
<li><a class="reference internal" href="#javascript-callbacks">Javascript callbacks</a
|
|
510
|
-
<li><a class="reference internal" href="#using-callbacks">Using callbacks</a></li>
|
|
509
|
+
<li><a class="reference internal" href="#javascript-callbacks">Javascript callbacks</a></li>
|
|
511
510
|
<li><a class="reference internal" href="#thread-safety">Thread safety</a></li>
|
|
512
511
|
</ul>
|
|
513
512
|
</li>
|
|
514
|
-
</ul>
|
|
515
|
-
</li>
|
|
516
513
|
</ul>
|
|
517
514
|
|
|
518
515
|
</div>
|
package/doc/dist/html/index.html
CHANGED
|
@@ -204,7 +204,7 @@
|
|
|
204
204
|
</div>
|
|
205
205
|
<article role="main">
|
|
206
206
|
<section id="koffi-version">
|
|
207
|
-
<h1>Koffi 1.3.
|
|
207
|
+
<h1>Koffi 1.3.5<a class="headerlink" href="#koffi-version" title="Permalink to this heading">#</a></h1>
|
|
208
208
|
<section id="overview">
|
|
209
209
|
<h2>Overview<a class="headerlink" href="#overview" title="Permalink to this heading">#</a></h2>
|
|
210
210
|
<p>Koffi is a <strong>fast and easy-to-use C FFI module for Node.js</strong>, featuring:</p>
|
|
@@ -240,6 +240,7 @@
|
|
|
240
240
|
<li class="toctree-l2"><a class="reference internal" href="functions#variadic-functions">Variadic functions</a></li>
|
|
241
241
|
<li class="toctree-l2"><a class="reference internal" href="functions#output-parameters">Output parameters</a></li>
|
|
242
242
|
<li class="toctree-l2"><a class="reference internal" href="functions#javascript-callbacks">Javascript callbacks</a></li>
|
|
243
|
+
<li class="toctree-l2"><a class="reference internal" href="functions#thread-safety">Thread safety</a></li>
|
|
243
244
|
</ul>
|
|
244
245
|
</li>
|
|
245
246
|
<li class="toctree-l1"><a class="reference internal" href="memory">Memory usage</a><ul>
|
|
@@ -263,6 +264,7 @@
|
|
|
263
264
|
</ul>
|
|
264
265
|
</li>
|
|
265
266
|
<li class="toctree-l1"><a class="reference internal" href="changes">Changelog</a><ul>
|
|
267
|
+
<li class="toctree-l2"><a class="reference internal" href="changes#koffi-1-3-5">Koffi 1.3.5</a></li>
|
|
266
268
|
<li class="toctree-l2"><a class="reference internal" href="changes#koffi-1-3-4">Koffi 1.3.4</a></li>
|
|
267
269
|
<li class="toctree-l2"><a class="reference internal" href="changes#koffi-1-3-3">Koffi 1.3.3</a></li>
|
|
268
270
|
<li class="toctree-l2"><a class="reference internal" href="changes#koffi-1-3-2">Koffi 1.3.2</a></li>
|
|
@@ -330,7 +332,7 @@
|
|
|
330
332
|
<div class="toc-tree-container">
|
|
331
333
|
<div class="toc-tree">
|
|
332
334
|
<ul>
|
|
333
|
-
<li><a class="reference internal" href="#">Koffi 1.3.
|
|
335
|
+
<li><a class="reference internal" href="#">Koffi 1.3.5</a><ul>
|
|
334
336
|
<li><a class="reference internal" href="#overview">Overview</a></li>
|
|
335
337
|
<li><a class="reference internal" href="#table-of-contents">Table of contents</a></li>
|
|
336
338
|
<li><a class="reference internal" href="#license">License</a></li>
|
|
@@ -209,7 +209,7 @@
|
|
|
209
209
|
<h2>How it works<a class="headerlink" href="#how-it-works" title="Permalink to this heading">#</a></h2>
|
|
210
210
|
<p>For synchronous/normal calls, Koffi uses two preallocated memory blocks:</p>
|
|
211
211
|
<ul class="simple">
|
|
212
|
-
<li><p>One to construct
|
|
212
|
+
<li><p>One to construct the C stack and assign registers, subsequently used by the platform-specific assembly code (1 MiB by default)</p></li>
|
|
213
213
|
<li><p>One to allocate strings and big objects/structs (2 MiB by default)</p></li>
|
|
214
214
|
</ul>
|
|
215
215
|
<p>Unless very big strings or objects (at least more than one page of memory) are used, no extra allocation ever happens during calls or callbacks.</p>
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
</pre></div>
|
|
220
220
|
</div>
|
|
221
221
|
<p>The same is true for asynchronous calls. When an asynchronous call is made, Koffi will allocate new blocks unless there is an unused (resident) set of blocks still available. Once the asynchronous call is finished, these blocks are freed if there are more than <code class="docutils literal notranslate"><span class="pre">resident_async_pools</span></code> sets of blocks left around.</p>
|
|
222
|
+
<p>There cannot be more than <code class="docutils literal notranslate"><span class="pre">max_async_calls</span></code> running at the same time.</p>
|
|
222
223
|
</section>
|
|
223
224
|
<section id="default-settings">
|
|
224
225
|
<h2>Default settings<a class="headerlink" href="#default-settings" title="Permalink to this heading">#</a></h2>
|
|
@@ -240,17 +241,21 @@
|
|
|
240
241
|
<td><p>Heap size for synchronous calls</p></td>
|
|
241
242
|
</tr>
|
|
242
243
|
<tr class="row-even"><td><p>async_stack_size</p></td>
|
|
243
|
-
<td><p>
|
|
244
|
+
<td><p>256 kiB</p></td>
|
|
244
245
|
<td><p>Stack size for asynchronous calls</p></td>
|
|
245
246
|
</tr>
|
|
246
247
|
<tr class="row-odd"><td><p>async_heap_size</p></td>
|
|
247
|
-
<td><p>
|
|
248
|
+
<td><p>512 kiB</p></td>
|
|
248
249
|
<td><p>Heap size for asynchronous calls</p></td>
|
|
249
250
|
</tr>
|
|
250
251
|
<tr class="row-even"><td><p>resident_async_pools</p></td>
|
|
251
252
|
<td><p>2</p></td>
|
|
252
253
|
<td><p>Number of resident pools for asynchronous calls</p></td>
|
|
253
254
|
</tr>
|
|
255
|
+
<tr class="row-odd"><td><p>max_async_calls</p></td>
|
|
256
|
+
<td><p>64</p></td>
|
|
257
|
+
<td><p>Maximum number of ongoing asynchronous calls</p></td>
|
|
258
|
+
</tr>
|
|
254
259
|
</tbody>
|
|
255
260
|
</table>
|
|
256
261
|
</div>
|
|
Binary file
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head><meta charset="utf-8"/>
|
|
4
4
|
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
5
5
|
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
|
|
6
|
-
<link rel="index" title="Index" href="genindex" /><link rel="search" title="Search" href="search" /><link rel="next" title="Quick start" href="start" /><link rel="prev" title="Koffi 1.3.
|
|
6
|
+
<link rel="index" title="Index" href="genindex" /><link rel="search" title="Search" href="search" /><link rel="next" title="Quick start" href="start" /><link rel="prev" title="Koffi 1.3.5" href="index" />
|
|
7
7
|
|
|
8
8
|
<meta name="generator" content="sphinx-5.0.1, furo 2022.06.04.1"/>
|
|
9
9
|
<title>Supported platforms - Koffi</title>
|