node-ctypes 1.3.0 → 1.4.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/build/Release/ctypes-darwin-arm64.node +0 -0
- package/build/Release/ctypes-darwin-x64.node +0 -0
- package/build/Release/ctypes-linux-arm64.node +0 -0
- package/build/Release/ctypes-linux-x64.node +0 -0
- package/build/Release/ctypes-win32-arm64.node +0 -0
- package/build/Release/ctypes-win32-x64.node +0 -0
- package/lib/core/Library.js +63 -31
- package/lib/index.d.ts +5 -1
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/core/Library.js
CHANGED
|
@@ -74,6 +74,15 @@ export function createLibraryClasses(Library, LRUCache, _toNativeType, _toNative
|
|
|
74
74
|
if (prop === "argtypes") return argtypes;
|
|
75
75
|
if (prop === "restype") return restype;
|
|
76
76
|
if (prop === "errcheck") return cachedFunc ? cachedFunc.errcheck : undefined;
|
|
77
|
+
if (prop === "callAsync") {
|
|
78
|
+
if (restype === undefined) {
|
|
79
|
+
throw new Error(`Function ${name}: restype not set`);
|
|
80
|
+
}
|
|
81
|
+
if (!cachedFunc) {
|
|
82
|
+
cachedFunc = cdll.func(name, restype, argtypes);
|
|
83
|
+
}
|
|
84
|
+
return cachedFunc.callAsync;
|
|
85
|
+
}
|
|
77
86
|
return target[prop];
|
|
78
87
|
},
|
|
79
88
|
set(target, prop, value) {
|
|
@@ -172,39 +181,19 @@ export function createLibraryClasses(Library, LRUCache, _toNativeType, _toNative
|
|
|
172
181
|
let callMethod;
|
|
173
182
|
|
|
174
183
|
if (argCount === 0) {
|
|
175
|
-
// FAST PATH: No arguments -
|
|
176
|
-
callMethod = function () {
|
|
177
|
-
|
|
184
|
+
// FAST PATH: No declared arguments - but still support variadic
|
|
185
|
+
callMethod = function (...args) {
|
|
186
|
+
if (args.length === 0) {
|
|
187
|
+
return ffiFunc.call();
|
|
188
|
+
}
|
|
189
|
+
// Variadic: pass all args directly
|
|
190
|
+
return ffiFunc.call(...args);
|
|
178
191
|
};
|
|
179
192
|
} else if (allPrimitive) {
|
|
180
|
-
// FAST PATH: All primitive args -
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
}
|
|
193
|
+
// FAST PATH: All primitive args - use rest args to support variadic
|
|
194
|
+
callMethod = function (...args) {
|
|
195
|
+
return ffiFunc.call(...args);
|
|
196
|
+
};
|
|
208
197
|
} else {
|
|
209
198
|
// SLOW PATH: Has buffer/struct args - need to extract _buffer
|
|
210
199
|
callMethod = function (...args) {
|
|
@@ -237,11 +226,54 @@ export function createLibraryClasses(Library, LRUCache, _toNativeType, _toNative
|
|
|
237
226
|
};
|
|
238
227
|
}
|
|
239
228
|
|
|
229
|
+
// =========================================================================
|
|
230
|
+
// ASYNC WRAPPER: same argument processing, but calls callAsync
|
|
231
|
+
// Returns a Promise instead of the result directly
|
|
232
|
+
// =========================================================================
|
|
233
|
+
|
|
234
|
+
let asyncCallMethod;
|
|
235
|
+
|
|
236
|
+
if (argCount === 0) {
|
|
237
|
+
asyncCallMethod = function (...args) {
|
|
238
|
+
if (args.length === 0) {
|
|
239
|
+
return ffiFunc.callAsync();
|
|
240
|
+
}
|
|
241
|
+
// Variadic: pass all args directly
|
|
242
|
+
return ffiFunc.callAsync(...args);
|
|
243
|
+
};
|
|
244
|
+
} else if (allPrimitive) {
|
|
245
|
+
asyncCallMethod = function (...args) {
|
|
246
|
+
return ffiFunc.callAsync(...args);
|
|
247
|
+
};
|
|
248
|
+
} else {
|
|
249
|
+
asyncCallMethod = function (...args) {
|
|
250
|
+
const processedArgs = [];
|
|
251
|
+
|
|
252
|
+
for (let i = 0; i < args.length; i++) {
|
|
253
|
+
const arg = args[i];
|
|
254
|
+
if (arg && typeof arg === "object") {
|
|
255
|
+
if (arg._buffer !== undefined && Buffer.isBuffer(arg._buffer)) {
|
|
256
|
+
processedArgs.push(arg._buffer);
|
|
257
|
+
} else if (Buffer.isBuffer(arg)) {
|
|
258
|
+
processedArgs.push(arg);
|
|
259
|
+
} else {
|
|
260
|
+
processedArgs.push(arg);
|
|
261
|
+
}
|
|
262
|
+
} else {
|
|
263
|
+
processedArgs.push(arg);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return ffiFunc.callAsync(...processedArgs);
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
240
271
|
// Aggiungi metadata come proprietà non-enumerable per non interferire
|
|
241
272
|
Object.defineProperties(callMethod, {
|
|
242
273
|
funcName: { value: name },
|
|
243
274
|
address: { value: ffiFunc.address },
|
|
244
275
|
_ffi: { value: ffiFunc },
|
|
276
|
+
callAsync: { value: asyncCallMethod, writable: false, enumerable: false, configurable: false },
|
|
245
277
|
// Esponi errcheck come setter/getter
|
|
246
278
|
errcheck: {
|
|
247
279
|
get() {
|
package/lib/index.d.ts
CHANGED
|
@@ -79,6 +79,8 @@ export type ErrcheckCallback = (result: any, func: CallableFunction, args: any[]
|
|
|
79
79
|
/** FFI function wrapper */
|
|
80
80
|
export interface FFIFunction {
|
|
81
81
|
(...args: any[]): any;
|
|
82
|
+
/** Async version: executes the native call on a worker thread, returns a Promise */
|
|
83
|
+
callAsync(...args: any[]): Promise<any>;
|
|
82
84
|
readonly funcName: string;
|
|
83
85
|
readonly address: bigint;
|
|
84
86
|
errcheck: ErrcheckCallback | null;
|
|
@@ -87,7 +89,7 @@ export interface FFIFunction {
|
|
|
87
89
|
/** CDLL - C calling convention library */
|
|
88
90
|
export class CDLL {
|
|
89
91
|
constructor(path: string | null);
|
|
90
|
-
func(name: string, returnType: AnyType, argTypes?: AnyType[], options?: FunctionOptions): CallableFunction & { errcheck: ErrcheckCallback | null };
|
|
92
|
+
func(name: string, returnType: AnyType, argTypes?: AnyType[], options?: FunctionOptions): CallableFunction & { callAsync(...args: any[]): Promise<any>; errcheck: ErrcheckCallback | null };
|
|
91
93
|
symbol(name: string): bigint;
|
|
92
94
|
close(): void;
|
|
93
95
|
readonly path: string;
|
|
@@ -99,6 +101,8 @@ export class CDLL {
|
|
|
99
101
|
/** FunctionWrapper for Python-like argtypes/restype syntax */
|
|
100
102
|
export interface FunctionWrapper {
|
|
101
103
|
(...args: any[]): any;
|
|
104
|
+
/** Async version: executes the native call on a worker thread, returns a Promise */
|
|
105
|
+
callAsync(...args: any[]): Promise<any>;
|
|
102
106
|
argtypes: AnyType[];
|
|
103
107
|
restype: AnyType;
|
|
104
108
|
errcheck: ErrcheckCallback | null;
|