Comparing version 2.3.21-beta.4 to 2.4.1
@@ -5,2 +5,19 @@ # Changelog | ||
### Koffi 2.4 | ||
#### Koffi 2.4.1 | ||
**Main changes:** | ||
- Support decoding pointers to callable functions | ||
- Support calling function pointers with [koffi.call()] | ||
- Deprecate `koffi.callback` in favor of `koffi.proto` | ||
**Other changes:** | ||
- Increase maximum number of callbacks to 8192 | ||
- Build Koffi with static CRT on Windows | ||
- Reorganize Koffi data conversion documentation | ||
- Add deprecated `koffi.handle` to TS file | ||
### Koffi 2.3 | ||
@@ -137,3 +154,3 @@ | ||
- Fix type parser issues (such as ignoring some [disposable qualifiers](calls.md#heap-allocated-values)) | ||
- Fix type parser issues (such as ignoring some [disposable qualifiers](parameters.md#heap-allocated-values)) | ||
- Fix crash when using disposable types in output parameters | ||
@@ -160,3 +177,3 @@ - Add basic [koffi.stats()](misc.md#usage-statistics) interface | ||
- Allow buffers (TypedArray or ArrayBuffer) values for input and/or output pointer arguments (for polymorphic arguments) | ||
- Support opaque buffers (TypedArray or ArrayBuffer) values in `koffi.decode()` to [decode output buffers](calls.md#output-buffers) | ||
- Support opaque buffers (TypedArray or ArrayBuffer) values in `koffi.decode()` to [decode output buffers](parameters.md#output-buffers) | ||
- Decode non-string types as arrays when an [explicit length is passed to koffi.decode()](callbacks.md#decoding-pointer-arguments) | ||
@@ -226,3 +243,3 @@ | ||
- Add [koffi.decode()](callbacks.md#decoding-pointer-arguments) for callback pointer arguments | ||
- Support transparent [output string parameters](calls.md#output-parameters) | ||
- Support transparent [output string parameters](parameters.md#output-parameters) | ||
- Add `koffi.offsetof()` utility function | ||
@@ -277,3 +294,3 @@ - Support optional *this* binding in `koffi.register()` | ||
- Add [koffi.as()](calls.md#polymorphic-parameters) to support polymorphic APIs based on `void *` parameters | ||
- Add [koffi.as()](parameters.md#polymorphic-parameters) to support polymorphic APIs based on `void *` parameters | ||
- Add [endian-sensitive integer types](types.md#endian-sensitive-types): `intX_le_t`, `intX_be_t`, `uintX_le_t`, `uintX_be_t` | ||
@@ -304,3 +321,3 @@ - Accept typed arrays for `void *` parameters | ||
- Add [disposable types](calls.md#heap-allocated-values) for automatic disposal of C values (such as heap-allocated strings) | ||
- Add [disposable types](parameters.md#heap-allocated-values) for automatic disposal of C values (such as heap-allocated strings) | ||
- Add support for [registered callbacks](callbacks.md#registered-callbacks), that can be called after the initial FFI call | ||
@@ -307,0 +324,0 @@ - Support named pointer types |
# Callbacks | ||
*Changed in Koffi 2.4* | ||
```{note} | ||
The function `koffi.proto()` was introduced in Koffi 2.4, it was called `koffi.callback()` in earlier versions. | ||
``` | ||
## Callback types | ||
@@ -11,6 +17,6 @@ | ||
// With the classic syntax, this callback expects an integer and returns nothing | ||
const ExampleCallback = koffi.callback('ExampleCallback', 'void', ['int']); | ||
const ExampleCallback = koffi.proto('ExampleCallback', 'void', ['int']); | ||
// With the prototype parser, this callback expects a double and float, and returns the sum as a double | ||
const AddDoubleFloat = koffi.callback('double AddDoubleFloat(double d, float f)'); | ||
const AddDoubleFloat = koffi.proto('double AddDoubleFloat(double d, float f)'); | ||
``` | ||
@@ -60,3 +66,3 @@ | ||
const TransferCallback = koffi.callback('int TransferCallback(const char *str, int age)'); | ||
const TransferCallback = koffi.proto('int TransferCallback(const char *str, int age)'); | ||
@@ -109,4 +115,4 @@ const TransferToJS = lib.func('TransferToJS', 'int', ['str', 'int', koffi.pointer(TransferCallback)]); | ||
const GetCallback = koffi.callback('const char *GetCallback(const char *name)'); | ||
const PrintCallback = koffi.callback('void PrintCallback(const char *str)'); | ||
const GetCallback = koffi.proto('const char *GetCallback(const char *name)'); | ||
const PrintCallback = koffi.proto('void PrintCallback(const char *str)'); | ||
@@ -161,3 +167,3 @@ const RegisterFunctions = lib.func('void RegisterFunctions(GetCallback *cb1, PrintCallback *cb2)'); | ||
const SortCallback = koffi.callback('int SortCallback(const void *first, const void *second)'); | ||
const SortCallback = koffi.proto('int SortCallback(const void *first, const void *second)'); | ||
const qsort = lib.func('void qsort(_Inout_ void *array, size_t count, size_t size, SortCallback *cb)'); | ||
@@ -164,0 +170,0 @@ |
@@ -1,2 +0,2 @@ | ||
# Library functions | ||
# Native functions | ||
@@ -91,1 +91,55 @@ ## Loading libraries | ||
``` | ||
## Function calls | ||
### Synchronous calls | ||
Once a native function has been declared, you can simply call it as you would any other JS function. | ||
```js | ||
const atoi = lib.func('int atoi(const char *str)'); | ||
let value = atoi('1257'); | ||
console.log(value); | ||
``` | ||
For [variadic functions](functions.md#variadic-functions), you msut specificy the type and the value for each additional argument. | ||
```js | ||
const printf = lib.func('printf', 'int', ['str', '...']); | ||
// The variadic arguments are: 6 (int), 8.5 (double), 'THE END' (const char *) | ||
printf('Integer %d, double %g, str %s', 'int', 6, 'double', 8.5, 'str', 'THE END'); | ||
``` | ||
### Asynchronous calls | ||
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. | ||
```js | ||
const koffi = require('koffi'); | ||
const lib = koffi.load('libc.so.6'); | ||
const atoi = lib.func('int atoi(const char *str)'); | ||
atoi.async('1257', (err, res) => { | ||
console.log('Result:', res); | ||
}) | ||
console.log('Hello World!'); | ||
// This program will print: | ||
// Hello World! | ||
// Result: 1257 | ||
``` | ||
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. | ||
You can easily convert this callback-style async function to a promise-based version with `util.promisify()` from the Node.js standard library. | ||
Variadic functions cannot be called asynchronously. | ||
## Thread safety | ||
Asynchronous functions run on worker threads. You need to deal with thread safety issues if you share data between threads. | ||
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! |
@@ -35,3 +35,3 @@ # Migration guide | ||
const TransferCallback = koffi.callback('int TransferCallback(const char *str, int age)'); | ||
const TransferCallback = koffi.proto('int TransferCallback(const char *str, int age)'); | ||
@@ -52,3 +52,3 @@ const TransferToJS = lib.func('TransferToJS', 'int', ['str', 'int', TransferCallback]); | ||
const TransferCallback = koffi.callback('int TransferCallback(const char *str, int age)'); | ||
const TransferCallback = koffi.proto('int TransferCallback(const char *str, int age)'); | ||
@@ -68,2 +68,6 @@ const TransferToJS = lib.func('TransferToJS', 'int', ['str', 'int', koffi.pointer(TransferCallback)]); | ||
```{note} | ||
The function `koffi.proto()` was introduced in Koffi 2.4, it was called `koffi.callback()` in earlier versions. | ||
``` | ||
### Opaque types | ||
@@ -70,0 +74,0 @@ |
@@ -129,3 +129,3 @@ # Data pointers | ||
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](calls.md#output-parameters). | ||
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](parameters.md#output-parameters). | ||
@@ -136,3 +136,3 @@ ## Disposable types | ||
Read the documentation for [disposable types](calls.md#heap-allocated-values) on the page about function calls. | ||
Read the documentation for [disposable types](parameters.md#heap-allocated-values) on the page about function calls. | ||
@@ -139,0 +139,0 @@ ## Unwrap pointers |
@@ -145,3 +145,3 @@ # Data types | ||
In Koffi, you can manage this with opaque types. Declare the opaque type with `koffi.opaque(name)`, and use a pointer to this type either as a return type or some kind of [output parameter](calls.md#output-parameters) (with a double pointer). | ||
In Koffi, you can manage this with opaque types. Declare the opaque type with `koffi.opaque(name)`, and use a pointer to this type either as a return type or some kind of [output parameter](parameters.md#output-parameters) (with a double pointer). | ||
@@ -153,3 +153,3 @@ ```{note} | ||
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](calls.md#output-parameters). | ||
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](parameters.md#output-parameters). | ||
@@ -156,0 +156,0 @@ In addition to this, you should use `koffi.opaque()` (introduced in Koffi 2.1) instead of `koffi.handle()` which is deprecated, and will be removed eventually in Koffi 3.0. |
{ | ||
"name": "koffi", | ||
"version": "2.3.21-beta.4", | ||
"stable": "2.3.20", | ||
"version": "2.4.1", | ||
"stable": "2.4.1", | ||
"description": "Fast and simple C FFI (foreign function interface) for Node.js", | ||
@@ -6,0 +6,0 @@ "keywords": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 21 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 21 instances in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
67597963
0