Skip to content

Commit 9462e4d

Browse files
committed
more
1 parent 76c9b68 commit 9462e4d

19 files changed

+2823
-2308
lines changed

doc/api/ffi.md

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ console.log(lib.symbols.abs(-42));
6868

6969
Each symbol signature is an object with the following fields:
7070

71-
* `parameters` {string\[]} Array of argument types.
72-
* `result` {string} Return type.
71+
* `parameters` {(string|Object)\[]} Array of argument types.
72+
* `result` {string|Object} Return type.
7373

7474
Supported type names:
7575

@@ -80,6 +80,11 @@ Supported type names:
8080
* `i64`, `u64`
8181
* `f32`, `f64`
8282
* `pointer`
83+
* `bool`
84+
* `buffer`
85+
* `function`
86+
* `usize`, `isize`
87+
* Struct descriptor objects: `{ struct: [/* field types */] }`
8388

8489
### `library.symbols`
8590

@@ -112,6 +117,67 @@ PointerObjects are created by:
112117
* `library.getSymbol(name)` - Get function pointer from library
113118
* `UnsafePointer.offset(pointer, offset)` - Create offset pointer
114119

120+
## Struct types
121+
122+
Struct types are expressed inline as type descriptors instead of a class.
123+
124+
* Struct descriptor: `{ struct: [fieldType1, fieldType2, ...] }`
125+
* Each field type can be any supported native type string or another struct
126+
descriptor.
127+
128+
### Using struct descriptors with `dlopen()`
129+
130+
```mjs
131+
import { dlopen } from 'node:ffi';
132+
133+
const Point = { struct: ['i32', 'i32'] };
134+
135+
const lib = dlopen('./mylib.so', {
136+
make_point: {
137+
parameters: ['i32', 'i32'],
138+
result: Point,
139+
},
140+
point_distance_squared: {
141+
parameters: [Point, Point],
142+
result: 'i32',
143+
},
144+
});
145+
146+
const p = lib.symbols.make_point(3, 4);
147+
// Struct return values are raw bytes.
148+
console.log(p instanceof Uint8Array); // true
149+
150+
const q = new Uint8Array(8);
151+
new DataView(q.buffer).setInt32(0, 0, true);
152+
new DataView(q.buffer).setInt32(4, 0, true);
153+
154+
console.log(lib.symbols.point_distance_squared(p, q)); // 25
155+
```
156+
157+
```cjs
158+
const { dlopen } = require('node:ffi');
159+
160+
const Point = { struct: ['i32', 'i32'] };
161+
162+
const lib = dlopen('./mylib.so', {
163+
make_point: {
164+
parameters: ['i32', 'i32'],
165+
result: Point,
166+
},
167+
point_distance_squared: {
168+
parameters: [Point, Point],
169+
result: 'i32',
170+
},
171+
});
172+
173+
const p = lib.symbols.make_point(3, 4);
174+
console.log(p instanceof Uint8Array); // true
175+
```
176+
177+
For struct parameters, pass an `ArrayBuffer` or `ArrayBufferView`
178+
(`Uint8Array`, `DataView`, etc.) containing bytes that match the target native
179+
struct layout.
180+
115181
## Class: `UnsafeFnPointer`
116182

117183
<!-- YAML
@@ -125,8 +191,8 @@ Create a callable wrapper around a function pointer.
125191
* `pointer` {PointerObject|bigint} A PointerObject or BigInt representing the
126192
function pointer address.
127193
* `definition` {Object} Function signature definition.
128-
* `parameters` {string\[]} Parameter types.
129-
* `result` {string} Return type.
194+
* `parameters` {(string|Object)\[]} Parameter types.
195+
* `result` {string|Object} Return type.
130196
* `nonblocking` {boolean} When `true`, function calls will run on a dedicated
131197
blocking thread and will return a Promise. **Default:** `false`.
132198

node.gyp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,15 @@
460460
'src/node_webstorage.h',
461461
],
462462
'node_ffi_sources': [
463-
'src/node_ffi.cc',
464-
'src/node_ffi.h',
463+
'src/ffi/dynamic_library.cc',
464+
'src/ffi/node_ffi.cc',
465+
'src/ffi/node_ffi.h',
466+
'src/ffi/pointer_object.cc',
467+
'src/ffi/types.cc',
468+
'src/ffi/unsafe_callback.cc',
469+
'src/ffi/unsafe_fn_pointer.cc',
470+
'src/ffi/unsafe_pointer.cc',
471+
'src/ffi/unsafe_pointer_view.cc',
465472
],
466473
'node_mksnapshot_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)node_mksnapshot<(EXECUTABLE_SUFFIX)',
467474
'node_js2c_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)node_js2c<(EXECUTABLE_SUFFIX)',

src/env_properties.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
V(arrow_message_private_symbol, "node:arrowMessage") \
2222
V(contextify_context_private_symbol, "node:contextify:context") \
2323
V(decorated_private_symbol, "node:decorated") \
24+
V(ffi_pointer_address_private_symbol, "node:ffi:pointer_address") \
2425
V(transfer_mode_private_symbol, "node:transfer_mode") \
2526
V(host_defined_option_symbol, "node:host_defined_option_symbol") \
2627
V(js_transferable_wrapper_private_symbol, "node:js_transferable_wrapper") \
@@ -404,6 +405,11 @@
404405
V(dns_ns_record_template, v8::DictionaryTemplate) \
405406
V(fd_constructor_template, v8::ObjectTemplate) \
406407
V(fdclose_constructor_template, v8::ObjectTemplate) \
408+
V(ffi_dynamic_library_constructor_template, v8::FunctionTemplate) \
409+
V(ffi_unsafe_callback_constructor_template, v8::FunctionTemplate) \
410+
V(ffi_unsafe_fn_pointer_constructor_template, v8::FunctionTemplate) \
411+
V(ffi_unsafe_pointer_constructor_template, v8::FunctionTemplate) \
412+
V(ffi_unsafe_pointer_view_constructor_template, v8::FunctionTemplate) \
407413
V(filehandlereadwrap_template, v8::ObjectTemplate) \
408414
V(free_list_statistics_template, v8::DictionaryTemplate) \
409415
V(fsreqpromise_constructor_template, v8::ObjectTemplate) \

0 commit comments

Comments
 (0)