node-ctypes 1.2.0 → 1.3.0

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/README.md CHANGED
@@ -221,15 +221,15 @@ console.log(u.f); // 42 reinterpreted as float
221
221
  ### Bit Fields - Compact Data Structures
222
222
 
223
223
  ```javascript
224
- import { Structure, bitfield, c_uint32 } from 'node-ctypes';
224
+ import { Structure, c_uint32 } from 'node-ctypes';
225
225
 
226
- // Bit fields for flags and compact data
226
+ // Bit fields using Python-style syntax: [name, type, bits]
227
227
  class Flags extends Structure {
228
228
  static _fields_ = [
229
- ["enabled", bitfield(c_uint32, 1)], // 1 bit
230
- ["mode", bitfield(c_uint32, 3)], // 3 bits
231
- ["priority", bitfield(c_uint32, 4)], // 4 bits
232
- ["reserved", bitfield(c_uint32, 24)] // 24 bits
229
+ ["enabled", c_uint32, 1], // 1 bit
230
+ ["mode", c_uint32, 3], // 3 bits
231
+ ["priority", c_uint32, 4], // 4 bits
232
+ ["reserved", c_uint32, 24] // 24 bits
233
233
  ];
234
234
  }
235
235
 
@@ -244,6 +244,19 @@ console.log(flags.mode); // 5
244
244
  console.log(flags.priority); // 12
245
245
  ```
246
246
 
247
+ **Alternative syntax with `bitfield()` helper:**
248
+
249
+ ```javascript
250
+ import { Structure, bitfield, c_uint32 } from 'node-ctypes';
251
+
252
+ class Flags extends Structure {
253
+ static _fields_ = [
254
+ ["enabled", bitfield(c_uint32, 1)],
255
+ ["mode", bitfield(c_uint32, 3)],
256
+ ];
257
+ }
258
+ ```
259
+
247
260
  ### Arrays - Fixed-size and Dynamic
248
261
 
249
262
  ```javascript
@@ -508,9 +521,33 @@ Benchmarked on Windows with Node.js v24.11.0:
508
521
  **Key Insights:**
509
522
  - koffi excels at simple operations and struct access
510
523
  - node-ctypes competitive on complex argument handling
511
- - **Struct performance gap**: koffi 15x faster due to direct object manipulation
524
+ - **Struct performance gap**: koffi ~13x faster due to plain object vs Proxy+N-API
525
+ - **Workaround**: Use `toObject()` for repeated struct reads (see below)
512
526
  - **Callback overhead**: koffi 1.5x faster at callback creation
513
527
 
528
+ ### Struct Performance Tip
529
+
530
+ When reading struct fields repeatedly (e.g., in a tight loop), use `toObject()` to convert to a plain JavaScript object:
531
+
532
+ ```javascript
533
+ const point = Point.create({ x: 10, y: 20 });
534
+
535
+ // ❌ Slow: Each access goes through Proxy → N-API → buffer read
536
+ for (let i = 0; i < 1000000; i++) {
537
+ const x = point.x; // ~80ns per access
538
+ }
539
+
540
+ // ✅ Fast: Convert once, then use plain object access
541
+ const obj = point.toObject(); // { x: 10, y: 20 }
542
+ for (let i = 0; i < 1000000; i++) {
543
+ const x = obj.x; // ~6ns per access (same as koffi!)
544
+ }
545
+ ```
546
+
547
+ **When to use direct access vs toObject():**
548
+ - **Direct access (`point.x`)**: Always synchronized with underlying buffer; required when C code modifies the buffer
549
+ - **`toObject()`**: Snapshot copy; use for read-only loops or when passing data to JS-only code
550
+
514
551
  **Transparent API overhead**: Only **3.5%** for auto `._buffer` extraction!
515
552
 
516
553
  *See `tests/benchmarks/` for full benchmark suite.*
@@ -623,7 +660,8 @@ puts(s);
623
660
 
624
661
  **Types and helpers**
625
662
  - `sizeof(type)` → `number` : size in bytes of a type.
626
- - `POINTER(baseType)` : creates a pointer type with helpers `create()`, `fromBuffer()`, `deref()`, `set()`.
663
+ - `POINTER(baseType)` : creates a pointer type factory (see [POINTER and pointer() API](#pointer-and-pointer-api) below).
664
+ - `pointer(obj)` : creates a pointer to an existing ctypes instance (Python-compatible).
627
665
  - `byref(buffer)` : passes a buffer by reference (Python ctypes compatibility).
628
666
  - `cast(ptr, targetType)` : interprets a pointer as another type (returns wrapper for struct).
629
667
 
@@ -700,6 +738,82 @@ Write a value to memory.
700
738
  #### `sizeof(type)` → `number`
701
739
  Get the size of a type in bytes.
702
740
 
741
+ #### POINTER and pointer() API
742
+
743
+ `node-ctypes` provides a Python ctypes-compatible pointer API:
744
+
745
+ ```javascript
746
+ import { POINTER, pointer, c_int32, Structure } from 'node-ctypes';
747
+
748
+ // Create a pointer type
749
+ const IntPtr = POINTER(c_int32);
750
+
751
+ // Create NULL pointer
752
+ const p1 = IntPtr.create();
753
+ console.log(p1.isNull); // true
754
+
755
+ // Create pointer from buffer
756
+ const buf = Buffer.alloc(12);
757
+ buf.writeInt32LE(10, 0);
758
+ buf.writeInt32LE(20, 4);
759
+ buf.writeInt32LE(30, 8);
760
+
761
+ const p2 = IntPtr.fromBuffer(buf);
762
+
763
+ // .contents property (Python-compatible)
764
+ console.log(p2.contents); // 10
765
+ p2.contents = 100;
766
+ console.log(buf.readInt32LE(0)); // 100
767
+
768
+ // Pointer indexing (Python-compatible)
769
+ console.log(p2[0]); // 100
770
+ console.log(p2[1]); // 20
771
+ console.log(p2[2]); // 30
772
+
773
+ p2[1] = 200;
774
+ console.log(buf.readInt32LE(4)); // 200
775
+
776
+ // pointer() function - create pointer to existing object
777
+ const x = new c_int32(42);
778
+ const px = pointer(x);
779
+ console.log(px.contents); // 42
780
+ px.contents = 100;
781
+ console.log(x.value); // 100
782
+
783
+ // Works with structures too
784
+ class Point extends Structure {
785
+ static _fields_ = [["x", c_int32], ["y", c_int32]];
786
+ }
787
+ const pt = new Point({ x: 10, y: 20 });
788
+ const ppt = pointer(pt);
789
+ ```
790
+
791
+ **POINTER type methods:**
792
+ - `POINTER(baseType)` - creates a pointer type factory
793
+ - `PointerType.create()` - creates a NULL pointer instance
794
+ - `PointerType.fromBuffer(buf)` - creates pointer to buffer
795
+ - `PointerType.fromAddress(addr)` - creates pointer from address
796
+
797
+ **Pointer instance properties:**
798
+ - `.contents` - get/set dereferenced value (Python-compatible)
799
+ - `.address` - get raw address as BigInt
800
+ - `.isNull` - check if pointer is NULL
801
+ - `[n]` - array-style indexing with pointer arithmetic
802
+ - `.deref()` - alias for `.contents` getter
803
+ - `.set(value)` - update pointer target
804
+
805
+ **Using POINTER in function definitions:**
806
+ ```javascript
807
+ // POINTER types can be used as argtypes and restype
808
+ const IntPtr = POINTER(c_int32);
809
+
810
+ // As argument type
811
+ const memset = msvcrt.func("memset", c_void_p, [IntPtr, c_int32, c_size_t]);
812
+
813
+ // As return type
814
+ const memchr = msvcrt.func("memchr", IntPtr, [c_void_p, c_int32, c_size_t]);
815
+ ```
816
+
703
817
  #### `struct(fields)` → `StructDefinition`
704
818
  Create a simple struct definition.
705
819
 
@@ -720,10 +834,11 @@ Base class for Python-like union definitions. Subclasses should define `static _
720
834
  | **Structs** | `class Point(Structure):`<br>&nbsp;&nbsp;`_fields_ = [("x", c_int)]` | `class Point extends Structure`<br>&nbsp;&nbsp;`{ static _fields_ = [["x", c_int]] }` |
721
835
  | **Unions** | `class U(Union):`<br>&nbsp;&nbsp;`_fields_ = [("i", c_int)]` | `class U extends Union`<br>&nbsp;&nbsp;`{ static _fields_ = [["i", c_int]] }` |
722
836
  | **Arrays** | `c_int * 5` | `array(c_int, 5)` |
723
- | **Bit fields** | `("flags", c_uint, 3)` | `bitfield(c_uint32, 3)` |
837
+ | **Bit fields** | `("flags", c_uint, 3)` | `["flags", c_uint32, 3]`<br>**or** `bitfield(c_uint32, 3)` |
724
838
  | **Callbacks** | `CFUNCTYPE(c_int, c_int)` | `callback(fn, c_int, [c_int])` |
725
839
  | **Strings** | `c_char_p(b"hello")` | `create_string_buffer("hello")`<br>**or**<br>`new c_char_p(b"hello")` |
726
- | **Pointers** | `POINTER(c_int)` | `c_void_p` |
840
+ | **Pointers** | `POINTER(c_int)`<br>`p.contents`<br>`p[0]` | `POINTER(c_int)`<br>`p.contents`<br>`p[0]` |
841
+ | **pointer()** | `pointer(obj)` | `pointer(obj)` |
727
842
  | **Variadic** | `sprintf(buf, b"%d", 42)` | `sprintf(buf, fmt, 42)` (auto) |
728
843
  | **Sizeof** | `sizeof(c_int)` | `sizeof(c_int)` |
729
844
 
Binary file
Binary file
@@ -51,255 +51,263 @@
51
51
  * @private
52
52
  */
53
53
  export function createLibraryClasses(Library, LRUCache, _toNativeType, _toNativeTypes, native) {
54
- class FunctionWrapper {
55
- constructor(cdll, name) {
56
- const argtypes = [];
57
- let restype = undefined;
58
- let cachedFunc = null;
54
+ class FunctionWrapper {
55
+ constructor(cdll, name) {
56
+ const argtypes = [];
57
+ let restype = undefined;
58
+ let cachedFunc = null;
59
59
 
60
- // Create a function and proxy it to make it callable
61
- const func = (...args) => {
62
- if (restype === undefined) {
63
- throw new Error(`Function ${name}: restype not set`);
64
- }
65
- if (!cachedFunc) {
66
- cachedFunc = cdll.func(name, restype, argtypes);
67
- }
68
- return cachedFunc(...args);
69
- };
70
-
71
- // Proxy the function to intercept property access
72
- return new Proxy(func, {
73
- get(target, prop) {
74
- if (prop === "argtypes") return argtypes;
75
- if (prop === "restype") return restype;
76
- if (prop === "errcheck") return cachedFunc ? cachedFunc.errcheck : undefined;
77
- return target[prop];
78
- },
79
- set(target, prop, value) {
80
- if (prop === "argtypes") {
81
- argtypes.splice(0, argtypes.length, ...value);
82
- cachedFunc = null; // Invalidate cache
83
- return true;
60
+ // Create a function and proxy it to make it callable
61
+ const func = (...args) => {
62
+ if (restype === undefined) {
63
+ throw new Error(`Function ${name}: restype not set`);
84
64
  }
85
- if (prop === "restype") {
86
- restype = value;
87
- cachedFunc = null; // Invalidate cache
88
- return true;
65
+ if (!cachedFunc) {
66
+ cachedFunc = cdll.func(name, restype, argtypes);
89
67
  }
90
- if (prop === "errcheck") {
91
- if (!cachedFunc) {
92
- if (restype === undefined) {
93
- throw new Error(`Function ${name}: restype not set`);
68
+ return cachedFunc(...args);
69
+ };
70
+
71
+ // Proxy the function to intercept property access
72
+ return new Proxy(func, {
73
+ get(target, prop) {
74
+ if (prop === "argtypes") return argtypes;
75
+ if (prop === "restype") return restype;
76
+ if (prop === "errcheck") return cachedFunc ? cachedFunc.errcheck : undefined;
77
+ return target[prop];
78
+ },
79
+ set(target, prop, value) {
80
+ if (prop === "argtypes") {
81
+ argtypes.splice(0, argtypes.length, ...value);
82
+ cachedFunc = null; // Invalidate cache
83
+ return true;
84
+ }
85
+ if (prop === "restype") {
86
+ restype = value;
87
+ cachedFunc = null; // Invalidate cache
88
+ return true;
89
+ }
90
+ if (prop === "errcheck") {
91
+ if (!cachedFunc) {
92
+ if (restype === undefined) {
93
+ throw new Error(`Function ${name}: restype not set`);
94
+ }
95
+ cachedFunc = cdll.func(name, restype, argtypes);
94
96
  }
95
- cachedFunc = cdll.func(name, restype, argtypes);
97
+ cachedFunc.errcheck = value;
98
+ return true;
96
99
  }
97
- cachedFunc.errcheck = value;
100
+ target[prop] = value;
98
101
  return true;
99
- }
100
- target[prop] = value;
101
- return true;
102
- },
103
- });
104
- }
105
- }
106
-
107
- /**
108
- * Wrapper conveniente per CDLL (come in Python ctypes)
109
- */
110
- class CDLL {
111
- constructor(libPath, options = {}) {
112
- this._lib = new Library(libPath);
113
- // Use LRU cache to prevent unbounded memory growth
114
- const cacheSize = options.cacheSize ?? 1000;
115
- this._cache = new LRUCache(cacheSize);
116
-
117
- // Return a proxy to enable Python-like syntax: libc.abs.argtypes = [...]; libc.abs.restype = ...; libc.abs(...)
118
- return new Proxy(this, {
119
- get(target, prop, receiver) {
120
- // Allow access to existing properties/methods
121
- if (prop in target || typeof prop !== "string") {
122
- return Reflect.get(target, prop, receiver);
123
- }
124
- // Assume it's a function name from the library
125
- return new FunctionWrapper(target, prop);
126
- },
127
- });
102
+ },
103
+ });
104
+ }
128
105
  }
129
106
 
130
107
  /**
131
- * Ottiene una funzione dalla libreria
132
- * @param {string} name - Nome della funzione
133
- * @param {Function|number|CType} returnType - Tipo di ritorno (SimpleCData class, CType value, o CType)
134
- * @param {Array<Function|number|CType>} argTypes - Tipi degli argomenti
135
- * @param {Object} [options] - Opzioni aggiuntive (es. { abi: 'stdcall' })
136
- * @returns {Function} Funzione callable
108
+ * Wrapper conveniente per CDLL (come in Python ctypes)
137
109
  */
138
- func(name, returnType, argTypes = [], options = {}) {
139
- const cacheKey = `${name}:${returnType}:${argTypes.join(",")}`;
110
+ class CDLL {
111
+ constructor(libPath, options = {}) {
112
+ this._lib = new Library(libPath);
113
+ // Use LRU cache to prevent unbounded memory growth
114
+ const cacheSize = options.cacheSize ?? 1000;
115
+ this._cache = new LRUCache(cacheSize);
116
+ // Cache for FunctionWrapper instances (Python-like syntax)
117
+ this._funcWrapperCache = new Map();
140
118
 
141
- if (this._cache.has(cacheKey)) {
142
- return this._cache.get(cacheKey);
119
+ // Return a proxy to enable Python-like syntax: libc.abs.argtypes = [...]; libc.abs.restype = ...; libc.abs(...)
120
+ return new Proxy(this, {
121
+ get(target, prop, receiver) {
122
+ // Allow access to existing properties/methods
123
+ if (prop in target || typeof prop !== "string") {
124
+ return Reflect.get(target, prop, receiver);
125
+ }
126
+ // Check if we already have a FunctionWrapper for this function name
127
+ if (target._funcWrapperCache.has(prop)) {
128
+ return target._funcWrapperCache.get(prop);
129
+ }
130
+ // Create and cache a new FunctionWrapper
131
+ const wrapper = new FunctionWrapper(target, prop);
132
+ target._funcWrapperCache.set(prop, wrapper);
133
+ return wrapper;
134
+ },
135
+ });
143
136
  }
144
137
 
145
- const ffiFunc = this._lib.func(name, _toNativeType(returnType, native), _toNativeTypes(argTypes, native), options);
138
+ /**
139
+ * Ottiene una funzione dalla libreria
140
+ * @param {string} name - Nome della funzione
141
+ * @param {Function|number|CType} returnType - Tipo di ritorno (SimpleCData class, CType value, o CType)
142
+ * @param {Array<Function|number|CType>} argTypes - Tipi degli argomenti
143
+ * @param {Object} [options] - Opzioni aggiuntive (es. { abi: 'stdcall' })
144
+ * @returns {Function} Funzione callable
145
+ */
146
+ func(name, returnType, argTypes = [], options = {}) {
147
+ const cacheKey = `${name}:${returnType}:${argTypes.join(",")}`;
146
148
 
147
- // =========================================================================
148
- // OPTIMIZATION: Create specialized wrapper based on argument types
149
- // For primitive-only args, bypass the processing loop entirely
150
- // =========================================================================
149
+ if (this._cache.has(cacheKey)) {
150
+ return this._cache.get(cacheKey);
151
+ }
151
152
 
152
- const argCount = argTypes.length;
153
+ const ffiFunc = this._lib.func(name, _toNativeType(returnType, native), _toNativeTypes(argTypes, native), options);
153
154
 
154
- // Check if all args are primitive types (no structs/buffers that need _buffer extraction)
155
- const allPrimitive = argTypes.every((t) => {
156
- if (typeof t === "function" && t._isSimpleCData) {
157
- // SimpleCData types that are NOT pointers are primitive
158
- const typeName = t._type;
159
- return typeName !== native.CType.POINTER && typeName !== native.CType.STRING && typeName !== native.CType.WSTRING;
160
- }
161
- return false;
162
- });
155
+ // =========================================================================
156
+ // OPTIMIZATION: Create specialized wrapper based on argument types
157
+ // For primitive-only args, bypass the processing loop entirely
158
+ // =========================================================================
163
159
 
164
- let callMethod;
160
+ const argCount = argTypes.length;
165
161
 
166
- if (argCount === 0) {
167
- // FAST PATH: No arguments - direct call
168
- callMethod = function () {
169
- return ffiFunc.call();
170
- };
171
- } else if (allPrimitive) {
172
- // FAST PATH: All primitive args - direct call without processing
173
- switch (argCount) {
174
- case 1:
175
- callMethod = function (a0) {
176
- return ffiFunc.call(a0);
177
- };
178
- break;
179
- case 2:
180
- callMethod = function (a0, a1) {
181
- return ffiFunc.call(a0, a1);
182
- };
183
- break;
184
- case 3:
185
- callMethod = function (a0, a1, a2) {
186
- return ffiFunc.call(a0, a1, a2);
187
- };
188
- break;
189
- case 4:
190
- callMethod = function (a0, a1, a2, a3) {
191
- return ffiFunc.call(a0, a1, a2, a3);
192
- };
193
- break;
194
- default:
195
- // Fallback for many args
196
- callMethod = function (...args) {
197
- return ffiFunc.call(...args);
198
- };
199
- }
200
- } else {
201
- // SLOW PATH: Has buffer/struct args - need to extract _buffer
202
- callMethod = function (...args) {
203
- const processedArgs = [];
162
+ // Check if all args are primitive types (no structs/buffers that need _buffer extraction)
163
+ const allPrimitive = argTypes.every((t) => {
164
+ if (typeof t === "function" && t._isSimpleCData) {
165
+ // SimpleCData types that are NOT pointers are primitive
166
+ const typeName = t._type;
167
+ return typeName !== native.CType.POINTER && typeName !== native.CType.STRING && typeName !== native.CType.WSTRING;
168
+ }
169
+ return false;
170
+ });
204
171
 
205
- for (let i = 0; i < args.length; i++) {
206
- const arg = args[i];
207
- // Check for _buffer FIRST (handles Proxy-wrapped structs)
208
- // This avoids calling Buffer.isBuffer() on Proxy which can cause issues
209
- if (arg && typeof arg === "object") {
210
- // Check for struct proxy FIRST - accessing _buffer on Proxy is safe
211
- // but Buffer.isBuffer(proxy) can cause hangs
212
- if (arg._buffer !== undefined && Buffer.isBuffer(arg._buffer)) {
213
- // Struct proxy or object with _buffer
214
- processedArgs.push(arg._buffer);
215
- } else if (Buffer.isBuffer(arg)) {
216
- // Already a buffer, use directly
217
- processedArgs.push(arg);
172
+ let callMethod;
173
+
174
+ if (argCount === 0) {
175
+ // FAST PATH: No arguments - direct call
176
+ callMethod = function () {
177
+ return ffiFunc.call();
178
+ };
179
+ } else if (allPrimitive) {
180
+ // FAST PATH: All primitive args - direct call without processing
181
+ switch (argCount) {
182
+ case 1:
183
+ callMethod = function (a0) {
184
+ return ffiFunc.call(a0);
185
+ };
186
+ break;
187
+ case 2:
188
+ callMethod = function (a0, a1) {
189
+ return ffiFunc.call(a0, a1);
190
+ };
191
+ break;
192
+ case 3:
193
+ callMethod = function (a0, a1, a2) {
194
+ return ffiFunc.call(a0, a1, a2);
195
+ };
196
+ break;
197
+ case 4:
198
+ callMethod = function (a0, a1, a2, a3) {
199
+ return ffiFunc.call(a0, a1, a2, a3);
200
+ };
201
+ break;
202
+ default:
203
+ // Fallback for many args
204
+ callMethod = function (...args) {
205
+ return ffiFunc.call(...args);
206
+ };
207
+ }
208
+ } else {
209
+ // SLOW PATH: Has buffer/struct args - need to extract _buffer
210
+ callMethod = function (...args) {
211
+ const processedArgs = [];
212
+
213
+ for (let i = 0; i < args.length; i++) {
214
+ const arg = args[i];
215
+ // Check for _buffer FIRST (handles Proxy-wrapped structs)
216
+ // This avoids calling Buffer.isBuffer() on Proxy which can cause issues
217
+ if (arg && typeof arg === "object") {
218
+ // Check for struct proxy FIRST - accessing _buffer on Proxy is safe
219
+ // but Buffer.isBuffer(proxy) can cause hangs
220
+ if (arg._buffer !== undefined && Buffer.isBuffer(arg._buffer)) {
221
+ // Struct proxy or object with _buffer
222
+ processedArgs.push(arg._buffer);
223
+ } else if (Buffer.isBuffer(arg)) {
224
+ // Already a buffer, use directly
225
+ processedArgs.push(arg);
226
+ } else {
227
+ // Other object, pass as-is
228
+ processedArgs.push(arg);
229
+ }
218
230
  } else {
219
- // Other object, pass as-is
231
+ // Primitive value (number, string, bigint, null, undefined)
220
232
  processedArgs.push(arg);
221
233
  }
222
- } else {
223
- // Primitive value (number, string, bigint, null, undefined)
224
- processedArgs.push(arg);
225
234
  }
226
- }
227
235
 
228
- return ffiFunc.call(...processedArgs);
229
- };
230
- }
236
+ return ffiFunc.call(...processedArgs);
237
+ };
238
+ }
231
239
 
232
- // Aggiungi metadata come proprietà non-enumerable per non interferire
233
- Object.defineProperties(callMethod, {
234
- funcName: { value: name },
235
- address: { value: ffiFunc.address },
236
- _ffi: { value: ffiFunc },
237
- // Esponi errcheck come setter/getter
238
- errcheck: {
239
- get() {
240
- return ffiFunc._errcheck;
241
- },
242
- set(callback) {
243
- ffiFunc._errcheck = callback;
244
- ffiFunc.setErrcheck(callback);
240
+ // Aggiungi metadata come proprietà non-enumerable per non interferire
241
+ Object.defineProperties(callMethod, {
242
+ funcName: { value: name },
243
+ address: { value: ffiFunc.address },
244
+ _ffi: { value: ffiFunc },
245
+ // Esponi errcheck come setter/getter
246
+ errcheck: {
247
+ get() {
248
+ return ffiFunc._errcheck;
249
+ },
250
+ set(callback) {
251
+ ffiFunc._errcheck = callback;
252
+ ffiFunc.setErrcheck(callback);
253
+ },
254
+ enumerable: false,
255
+ configurable: true,
245
256
  },
246
- enumerable: false,
247
- configurable: true,
248
- },
249
- });
257
+ });
250
258
 
251
- this._cache.set(cacheKey, callMethod);
252
- return callMethod;
253
- }
259
+ this._cache.set(cacheKey, callMethod);
260
+ return callMethod;
261
+ }
254
262
 
255
- /**
256
- * Ottiene l'indirizzo di un simbolo
257
- * @param {string} name - Nome del simbolo
258
- * @returns {BigInt} Indirizzo del simbolo
259
- */
260
- symbol(name) {
261
- return this._lib.symbol(name);
262
- }
263
+ /**
264
+ * Ottiene l'indirizzo di un simbolo
265
+ * @param {string} name - Nome del simbolo
266
+ * @returns {BigInt} Indirizzo del simbolo
267
+ */
268
+ symbol(name) {
269
+ return this._lib.symbol(name);
270
+ }
263
271
 
264
- /**
265
- * Crea un callback JS chiamabile da C
266
- * @param {Function} fn - Funzione JavaScript
267
- * @param {Function|number|CType} returnType - Tipo di ritorno (SimpleCData class, CType value, o CType)
268
- * @param {Array<Function|number|CType>} argTypes - Tipi degli argomenti
269
- * @returns {Object} Oggetto callback con proprietà pointer e metodi
270
- */
271
- callback(fn, returnType, argTypes = []) {
272
- return this._lib.callback(_toNativeType(returnType, native), _toNativeTypes(argTypes, native), fn);
273
- }
272
+ /**
273
+ * Crea un callback JS chiamabile da C
274
+ * @param {Function} fn - Funzione JavaScript
275
+ * @param {Function|number|CType} returnType - Tipo di ritorno (SimpleCData class, CType value, o CType)
276
+ * @param {Array<Function|number|CType>} argTypes - Tipi degli argomenti
277
+ * @returns {Object} Oggetto callback con proprietà pointer e metodi
278
+ */
279
+ callback(fn, returnType, argTypes = []) {
280
+ return this._lib.callback(_toNativeType(returnType, native), _toNativeTypes(argTypes, native), fn);
281
+ }
274
282
 
275
- /**
276
- * Chiude la libreria
277
- */
278
- close() {
279
- this._lib.close();
280
- this._cache.clear();
281
- }
283
+ /**
284
+ * Chiude la libreria
285
+ */
286
+ close() {
287
+ this._lib.close();
288
+ this._cache.clear();
289
+ }
282
290
 
283
- get path() {
284
- return this._lib.path;
285
- }
291
+ get path() {
292
+ return this._lib.path;
293
+ }
286
294
 
287
- get loaded() {
288
- return this._lib.loaded;
295
+ get loaded() {
296
+ return this._lib.loaded;
297
+ }
289
298
  }
290
- }
291
299
 
292
- /**
293
- * WinDLL - come CDLL ma con stdcall di default (per Windows)
294
- */
295
- class WinDLL extends CDLL {
296
- func(name, returnType, argTypes = [], options = {}) {
297
- return super.func(name, returnType, argTypes, {
298
- abi: "stdcall",
299
- ...options,
300
- });
300
+ /**
301
+ * WinDLL - come CDLL ma con stdcall di default (per Windows)
302
+ */
303
+ class WinDLL extends CDLL {
304
+ func(name, returnType, argTypes = [], options = {}) {
305
+ return super.func(name, returnType, argTypes, {
306
+ abi: "stdcall",
307
+ ...options,
308
+ });
309
+ }
301
310
  }
302
- }
303
311
 
304
312
  return { FunctionWrapper, CDLL, WinDLL };
305
313
  }