node-ctypes 0.1.3 → 0.1.4

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
@@ -93,10 +93,17 @@ print(p.x, p.y) # 10 20
93
93
  ```javascript
94
94
  import { CDLL, c_int, Structure } from 'node-ctypes';
95
95
 
96
+ // Traditional syntax (always available)
96
97
  const libc = new CDLL("libc.so.6");
97
98
  const abs = libc.func("abs", c_int, [c_int]);
98
99
  console.log(abs(-42)); // 42
99
100
 
101
+ // Python ctypes-like syntax
102
+ const abs_func = libc.abs;
103
+ abs_func.argtypes = [c_int];
104
+ abs_func.restype = c_int;
105
+ console.log(abs_func(-42)); // 42
106
+
100
107
  class Point extends Structure {
101
108
  static _fields_ = [
102
109
  ["x", c_int],
@@ -113,19 +120,25 @@ console.log(p.x, p.y); // 10 20
113
120
  ### Basic FFI - Calling C Functions
114
121
 
115
122
  ```javascript
116
- import { CDLL, c_int, c_double, c_char_p } from 'node-ctypes';
123
+ import { CDLL, c_int, c_double, c_char_p, c_size_t } from 'node-ctypes';
117
124
 
118
125
  // Load libc
119
126
  const libc = new CDLL('libc.so.6'); // Linux
120
127
  // const libc = new CDLL('msvcrt.dll'); // Windows
121
128
  // const libc = new CDLL('libc.dylib'); // macOS
122
129
 
123
- // Call abs() - integer absolute value
130
+ // Traditional syntax
124
131
  const abs = libc.func('abs', c_int, [c_int]);
125
132
  console.log(abs(-42)); // 42
126
133
 
134
+ // Python ctypes-like syntax (equivalent!)
135
+ const abs_func = libc.abs;
136
+ abs_func.argtypes = [c_int];
137
+ abs_func.restype = c_int;
138
+ console.log(abs_func(-42)); // 42
139
+
127
140
  // Call strlen() - string length
128
- const strlen = libc.func('strlen', 'size_t', [c_char_p]);
141
+ const strlen = libc.func('strlen', c_size_t, [c_char_p]);
129
142
  console.log(strlen('Hello')); // 5n (BigInt)
130
143
 
131
144
  // Load libm for math functions
@@ -228,10 +241,10 @@ console.log(flags.priority); // 12
228
241
  ### Arrays - Fixed-size and Dynamic
229
242
 
230
243
  ```javascript
231
- import { c_int, c_uint8, array } from 'node-ctypes';
244
+ import { c_int32, c_uint8, array } from 'node-ctypes';
232
245
 
233
246
  // Fixed-size array
234
- const IntArray = array('int32', 5);
247
+ const IntArray = array(c_int32, 5);
235
248
  const arr = IntArray.create([1, 2, 3, 4, 5]);
236
249
 
237
250
  // Array access
@@ -244,12 +257,12 @@ for (const val of arr) {
244
257
  }
245
258
 
246
259
  // Arrays in structs
247
- import { Structure, array } from 'node-ctypes';
260
+ import { Structure, array, c_uint8 } from 'node-ctypes';
248
261
 
249
262
  class Packet extends Structure {
250
263
  static _fields_ = [
251
- ["header", array("c_uint8", 8)],
252
- ["data", array("c_uint8", 256)]
264
+ ["header", array(c_uint8, 8)],
265
+ ["data", array(c_uint8, 256)]
253
266
  ];
254
267
  }
255
268
 
@@ -324,7 +337,7 @@ img.pixels[0].color.rgb.g = 128; // Works correctly!
324
337
  ### Callbacks - JavaScript Functions in C
325
338
 
326
339
  ```javascript
327
- import { CDLL, callback, c_int, c_void_p, readValue, writeValue, create_string_buffer } from 'node-ctypes';
340
+ import { CDLL, callback, c_int32, c_void, c_void_p, c_size_t, readValue, writeValue, create_string_buffer } from 'node-ctypes';
328
341
 
329
342
  const libc = new CDLL('msvcrt.dll'); // or libc.so.6 on Linux
330
343
 
@@ -332,8 +345,8 @@ const libc = new CDLL('msvcrt.dll'); // or libc.so.6 on Linux
332
345
  const compare = callback(
333
346
  (a, b) => {
334
347
  // a and b are pointers to int32 values
335
- const aVal = readValue(a, 'int32');
336
- const bVal = readValue(b, 'int32');
348
+ const aVal = readValue(a, c_int32);
349
+ const bVal = readValue(b, c_int32);
337
350
  return aVal - bVal;
338
351
  },
339
352
  c_int, // return type
@@ -341,21 +354,21 @@ const compare = callback(
341
354
  );
342
355
 
343
356
  // Sort an array using qsort
344
- const qsort = libc.func('qsort', 'void', [
357
+ const qsort = libc.func('qsort', c_void, [
345
358
  c_void_p, // array pointer
346
- 'size_t', // number of elements
347
- 'size_t', // element size
359
+ c_size_t, // number of elements
360
+ c_size_t, // element size
348
361
  c_void_p // comparison function
349
362
  ]);
350
363
 
351
364
  const arr = create_string_buffer(5 * 4);
352
365
  const values = [5, 2, 8, 1, 9];
353
- values.forEach((v, i) => writeValue(arr, 'int32', v, i * 4));
366
+ values.forEach((v, i) => writeValue(arr, c_int32, v, i * 4));
354
367
  qsort(arr, 5, 4, compare.pointer);
355
368
 
356
369
  // Array is now sorted: [1, 2, 5, 8, 9]
357
- console.log(readValue(arr, 'int32', 0)); // 1
358
- console.log(readValue(arr, 'int32', 4)); // 2
370
+ console.log(readValue(arr, c_int32, 0)); // 1
371
+ console.log(readValue(arr, c_int32, 4)); // 2
359
372
 
360
373
  // IMPORTANT: Release callback when done
361
374
  compare.release();
@@ -399,7 +412,7 @@ console.log(string_at(buffer)); // "Pi ≈ 3.14"
399
412
  ### Windows API - Full Support
400
413
 
401
414
  ```javascript
402
- import { WinDLL, Structure, c_uint16, c_void_p, c_wchar_p, c_int } from 'node-ctypes';
415
+ import { WinDLL, Structure, c_uint16, c_uint32, c_void_p, c_wchar_p, c_int } from 'node-ctypes';
403
416
 
404
417
  // WinDLL uses __stdcall convention (default for Windows API)
405
418
  const kernel32 = new WinDLL('kernel32.dll');
@@ -419,7 +432,7 @@ class SYSTEMTIME extends Structure {
419
432
  }
420
433
 
421
434
  // Get local time
422
- const GetLocalTime = kernel32.func('GetLocalTime', 'void', [c_void_p]);
435
+ const GetLocalTime = kernel32.func('GetLocalTime', c_void, [c_void_p]);
423
436
 
424
437
  const st = new SYSTEMTIME();
425
438
  GetLocalTime(st); // Pass struct directly - automatic _buffer extraction!
@@ -433,7 +446,7 @@ const MessageBoxW = user32.func('MessageBoxW', c_int, [
433
446
  c_void_p, // hWnd
434
447
  c_wchar_p, // lpText
435
448
  c_wchar_p, // lpCaption
436
- 'uint32' // uType
449
+ c_uint32 // uType
437
450
  ]);
438
451
 
439
452
  // Create UTF-16 buffers for wide strings
@@ -549,10 +562,18 @@ This section provides a more complete description of the APIs exported from `lib
549
562
 
550
563
  Example:
551
564
  ```js
552
- import { CDLL } from './lib/index.js';
565
+ import { CDLL, c_int32 } from './lib/index.js';
553
566
  const libc = new CDLL(null);
554
- const abs = libc.func('abs', 'int32', ['int32']);
567
+
568
+ // Traditional syntax
569
+ const abs = libc.func('abs', c_int32, [c_int32]);
555
570
  console.log(abs(-5));
571
+
572
+ // Python ctypes-like syntax
573
+ const abs_func = libc.abs;
574
+ abs_func.argtypes = [c_int32];
575
+ abs_func.restype = c_int32;
576
+ console.log(abs_func(-5));
556
577
  ```
557
578
 
558
579
  **Detailed CDLL API**
@@ -560,6 +581,7 @@ console.log(abs(-5));
560
581
  - automatically extracts `._buffer` from struct objects passed as arguments;
561
582
  - exposes non-enumerable metadata: `funcName`, `address`, `_ffi`;
562
583
  - provides the `errcheck` property as getter/setter to intercept return errors.
584
+ - **Python ctypes-like access**: `libc.functionName` returns a wrapper with `argtypes`/`restype`/`errcheck` properties for Python-compatible syntax.
563
585
  - `symbol(name)` → `BigInt` : address of a symbol.
564
586
  - `close()` : closes the library and clears the cache.
565
587
  - `path` (getter) : library path.
@@ -581,9 +603,9 @@ Note: always call `release()` when a callback is no longer needed.
581
603
 
582
604
  Example string creation and passing to function:
583
605
  ```js
584
- import { create_string_buffer, CDLL } from './lib/index.js';
606
+ import { create_string_buffer, CDLL, c_int32, c_void_p } from './lib/index.js';
585
607
  const libc = new CDLL(null);
586
- const puts = libc.func('puts', 'int32', ['pointer']);
608
+ const puts = libc.func('puts', c_int32, [c_void_p]);
587
609
  const s = create_string_buffer('hello');
588
610
  puts(s);
589
611
  ```
@@ -685,7 +707,7 @@ Base class for Python-like union definitions. Subclasses should define `static _
685
707
  | Feature | Python ctypes | node-ctypes |
686
708
  |---------|---------------|-------------|
687
709
  | **Load library** | `CDLL("lib.so")` | `new CDLL("lib.so")` |
688
- | **Define function** | `lib.func.argtypes = [c_int]`<br>`lib.func.restype = c_int` | `lib.func("func", c_int, [c_int])` |
710
+ | **Define function** | `lib.func.argtypes = [c_int]`<br>`lib.func.restype = c_int` | `lib.func("func", c_int, [c_int])`<br>**or**<br>`lib.func.argtypes = [c_int]`<br>`lib.func.restype = c_int` |
689
711
  | **Structs** | `class Point(Structure):`<br>&nbsp;&nbsp;`_fields_ = [("x", c_int)]` | `class Point extends Structure`<br>&nbsp;&nbsp;`{ static _fields_ = [["x", c_int]] }` |
690
712
  | **Unions** | `class U(Union):`<br>&nbsp;&nbsp;`_fields_ = [("i", c_int)]` | `class U extends Union`<br>&nbsp;&nbsp;`{ static _fields_ = [["i", c_int]] }` |
691
713
  | **Arrays** | `c_int * 5` | `array(c_int, 5)` |
@@ -715,8 +737,8 @@ Base class for Python-like union definitions. Subclasses should define `static _
715
737
  ⚠️ **Differences from Python ctypes**:
716
738
  - Structs use `.toObject()` for property access (eager loading for performance)
717
739
  - Callbacks must be manually released with `.release()`
718
- - Function definition is combined: `func(name, returnType, argTypes)` vs separate argtypes/restype
719
- - No `POINTER()` type - use `c_void_p` or type name string
740
+ - **Function definition supports both syntaxes**: `func(name, returnType, argTypes)` **or** `func.argtypes = [...]; func.restype = ...`
741
+ - No `POINTER()` type - use `c_void_p`
720
742
 
721
743
 
722
744
  ## Limitations & Known Issues
Binary file
Binary file
package/lib/index.d.ts CHANGED
@@ -108,12 +108,7 @@ export class Version {
108
108
  /** Native library handle */
109
109
  export class Library {
110
110
  constructor(path: string | null);
111
- func(
112
- name: string,
113
- returnType: CTypeString | CType,
114
- argTypes?: (CTypeString | CType)[],
115
- options?: FunctionOptions,
116
- ): FFIFunction;
111
+ func(name: string, returnType: CTypeString | CType, argTypes?: (CTypeString | CType)[], options?: FunctionOptions): FFIFunction;
117
112
  symbol(name: string): bigint;
118
113
  close(): void;
119
114
  readonly path: string;
@@ -126,11 +121,7 @@ export interface FunctionOptions {
126
121
  }
127
122
 
128
123
  /** Errcheck callback type */
129
- export type ErrcheckCallback = (
130
- result: any,
131
- func: CallableFunction,
132
- args: any[],
133
- ) => any;
124
+ export type ErrcheckCallback = (result: any, func: CallableFunction, args: any[]) => any;
134
125
 
135
126
  /** FFI function wrapper */
136
127
  export interface FFIFunction {
@@ -143,12 +134,7 @@ export interface FFIFunction {
143
134
  /** CDLL - C calling convention library */
144
135
  export class CDLL {
145
136
  constructor(path: string | null);
146
- func(
147
- name: string,
148
- returnType: CTypeString | CType,
149
- argTypes?: (CTypeString | CType)[],
150
- options?: FunctionOptions,
151
- ): CallableFunction & { errcheck: ErrcheckCallback | null };
137
+ func(name: string, returnType: CTypeString | CType, argTypes?: (CTypeString | CType)[], options?: FunctionOptions): CallableFunction & { errcheck: ErrcheckCallback | null };
152
138
  symbol(name: string): bigint;
153
139
  close(): void;
154
140
  readonly path: string;
@@ -172,11 +158,7 @@ export interface CallbackWrapper {
172
158
 
173
159
  /** Native Callback class */
174
160
  export class Callback {
175
- constructor(
176
- fn: Function,
177
- returnType: CTypeString | CType,
178
- argTypes?: (CTypeString | CType)[],
179
- );
161
+ constructor(fn: Function, returnType: CTypeString | CType, argTypes?: (CTypeString | CType)[]);
180
162
  readonly pointer: bigint;
181
163
  release(): void;
182
164
  }
@@ -220,31 +202,11 @@ export interface StructDef {
220
202
  }
221
203
 
222
204
  // Helper types for improved typed structs
223
- export type FieldSpec =
224
- | CTypeString
225
- | CType
226
- | StructDef
227
- | ArrayTypeDef
228
- | BitFieldDef
229
- | AnonymousField;
205
+ export type FieldSpec = CTypeString | CType | StructDef | ArrayTypeDef | BitFieldDef | AnonymousField;
230
206
 
231
207
  type JsFromCType<T> = T extends "int64" | "uint64" | "size_t"
232
208
  ? bigint
233
- : T extends
234
- | "int8"
235
- | "uint8"
236
- | "int16"
237
- | "uint16"
238
- | "int32"
239
- | "uint32"
240
- | "int"
241
- | "uint"
242
- | "short"
243
- | "ushort"
244
- | "char"
245
- | "uchar"
246
- | "float"
247
- | "double"
209
+ : T extends "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" | "int" | "uint" | "short" | "ushort" | "char" | "uchar" | "float" | "double"
248
210
  ? number
249
211
  : T extends "bool"
250
212
  ? boolean
@@ -331,10 +293,7 @@ export interface PointerTypeDef {
331
293
  /** Native StructType class */
332
294
  export class StructType {
333
295
  constructor(isUnion?: boolean);
334
- addField(
335
- name: string,
336
- type: CTypeString | CType | StructType | ArrayType,
337
- ): this;
296
+ addField(name: string, type: CTypeString | CType | StructType | ArrayType): this;
338
297
  getSize(): number;
339
298
  getAlignment(): number;
340
299
  create(values?: Record<string, any>): Buffer;
@@ -355,28 +314,17 @@ export class ArrayType {
355
314
  * Subclasses should define `static _fields_` as array of [name, type]
356
315
  * or an object map { name: type }.
357
316
  */
358
- export class Structure<
359
- F extends Record<string, FieldSpec> = Record<string, any>,
360
- > {
317
+ export class Structure<F extends Record<string, FieldSpec> = Record<string, any>> {
361
318
  constructor(...args: any[]);
362
319
  static _fields_?: Array<[string, FieldSpec]> | Record<string, FieldSpec>;
363
320
  static _pack_?: boolean;
364
321
  static _anonymous_?: string[];
365
- static create<ThisT extends Structure<F>>(
366
- this: new (...args: any[]) => ThisT,
367
- values?: Partial<FieldsToInstance<F>> | Buffer,
368
- ): ThisT;
369
- static toObject<ThisT extends Structure<F>>(
370
- this: new (...args: any[]) => ThisT,
371
- buf: Buffer | any,
372
- ): FieldsToInstance<F>;
322
+ static create<ThisT extends Structure<F>>(this: new (...args: any[]) => ThisT, values?: Partial<FieldsToInstance<F>> | Buffer): ThisT;
323
+ static toObject<ThisT extends Structure<F>>(this: new (...args: any[]) => ThisT, buf: Buffer | any): FieldsToInstance<F>;
373
324
  _buffer: Buffer;
374
325
  _structDef: StructDef;
375
326
  get<K extends keyof F & string>(fieldName: K): FieldsToInstance<F>[K];
376
- set<K extends keyof F & string>(
377
- fieldName: K,
378
- value: FieldsToInstance<F>[K],
379
- ): void;
327
+ set<K extends keyof F & string>(fieldName: K, value: FieldsToInstance<F>[K]): void;
380
328
  toObject(): FieldsToInstance<F>;
381
329
  [field: string]: any; // instance has dynamic properties for fields
382
330
  }
@@ -384,9 +332,7 @@ export class Structure<
384
332
  /**
385
333
  * Python-like Union base class.
386
334
  */
387
- export class Union<
388
- F extends Record<string, FieldSpec> = Record<string, any>,
389
- > extends Structure<F> {}
335
+ export class Union<F extends Record<string, FieldSpec> = Record<string, any>> extends Structure<F> {}
390
336
 
391
337
  // =============================================================================
392
338
  // Functions
@@ -396,85 +342,36 @@ export class Union<
396
342
  export function load(path: string | null): Library;
397
343
 
398
344
  // Callbacks
399
- export function callback(
400
- fn: Function,
401
- returnType: CTypeString | CType,
402
- argTypes?: (CTypeString | CType)[],
403
- ): CallbackWrapper;
404
- export function threadSafeCallback(
405
- fn: Function,
406
- returnType: CTypeString | CType,
407
- argTypes?: (CTypeString | CType)[],
408
- ): CallbackWrapper;
345
+ export function callback(fn: Function, returnType: CTypeString | CType, argTypes?: (CTypeString | CType)[]): CallbackWrapper;
346
+ export function threadSafeCallback(fn: Function, returnType: CTypeString | CType, argTypes?: (CTypeString | CType)[]): CallbackWrapper;
409
347
 
410
348
  // Memory management - Python-compatible
411
349
  export function create_string_buffer(init: number | string | Buffer): Buffer;
412
350
  export function create_unicode_buffer(init: number | string): Buffer;
413
- export function string_at(
414
- address: Buffer | bigint | number,
415
- size?: number,
416
- ): string | null;
417
- export function wstring_at(
418
- address: Buffer | bigint | number,
419
- size?: number,
420
- ): string | null;
351
+ export function string_at(address: Buffer | bigint | number, size?: number): string | null;
352
+ export function wstring_at(address: Buffer | bigint | number, size?: number): string | null;
421
353
  export function addressof(ptr: Buffer | bigint | number): bigint;
422
354
  export function memmove(dst: Buffer, src: Buffer | bigint, count: number): void;
423
355
  export function memset(dst: Buffer, value: number, count: number): void;
424
356
 
425
357
  // Memory - utility (no direct Python equivalent)
426
- export function readValue(
427
- ptr: Buffer | bigint | number,
428
- type: CTypeString | CType,
429
- offset?: number,
430
- ): any;
431
- export function writeValue(
432
- ptr: Buffer | bigint | number,
433
- type: CTypeString | CType,
434
- value: any,
435
- offset?: number,
436
- ): number;
437
- export function sizeof(
438
- type: CTypeString | CType | StructDef | ArrayTypeDef,
439
- ): number;
358
+ export function readValue(ptr: Buffer | bigint | number, type: CTypeString | CType, offset?: number): any;
359
+ export function writeValue(ptr: Buffer | bigint | number, type: CTypeString | CType, value: any, offset?: number): number;
360
+ export function sizeof(type: CTypeString | CType | StructDef | ArrayTypeDef): number;
440
361
  export function ptrToBuffer(address: bigint | number, size: number): Buffer;
441
362
 
442
363
  // Structures
443
- export function struct(
444
- fields: Record<
445
- string,
446
- | CTypeString
447
- | CType
448
- | StructDef
449
- | ArrayTypeDef
450
- | BitFieldDef
451
- | AnonymousField
452
- >,
453
- options?: StructOptions,
454
- ): StructDef;
455
- export function union(
456
- fields: Record<
457
- string,
458
- CTypeString | CType | StructDef | ArrayTypeDef | BitFieldDef
459
- >,
460
- ): UnionDef;
364
+ export function struct(fields: Record<string, CTypeString | CType | StructDef | ArrayTypeDef | BitFieldDef | AnonymousField>, options?: StructOptions): StructDef;
365
+ export function union(fields: Record<string, CTypeString | CType | StructDef | ArrayTypeDef | BitFieldDef>): UnionDef;
461
366
  // Factory helpers that return a typed class extending Structure/Union
462
- export function defineStruct<F extends Record<string, FieldSpec>>(
463
- fields: F,
464
- options?: StructOptions,
465
- ): new (...args: any[]) => Structure<F>;
466
- export function defineUnion<F extends Record<string, FieldSpec>>(
467
- fields: F,
468
- ): new (...args: any[]) => Union<F>;
367
+ export function defineStruct<F extends Record<string, FieldSpec>>(fields: F, options?: StructOptions): new (...args: any[]) => Structure<F>;
368
+ export function defineUnion<F extends Record<string, FieldSpec>>(fields: F): new (...args: any[]) => Union<F>;
469
369
  export function array(elementType: CTypeString, count: number): ArrayTypeDef;
470
370
  export function bitfield(baseType: CTypeString, bits: number): BitFieldDef;
471
371
 
472
372
  // Pointers
473
373
  export function byref(obj: Buffer): Buffer;
474
- export function cast(
475
- ptr: Buffer | bigint,
476
- targetType: CTypeString | StructDef,
477
- ): any;
374
+ export function cast(ptr: Buffer | bigint, targetType: CTypeString | StructDef): any;
478
375
  export function POINTER(baseType: CTypeString | StructDef): PointerTypeDef;
479
376
 
480
377
  // Error handling