@@ -68,8 +68,8 @@ console.log(lib.symbols.abs(-42));
6868
6969Each 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
7474Supported 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
0 commit comments