Type conversion

Implicit convert

In js-ctypes, data could be converted implicitly when passing to or returning from a FunctionType call, or setting pointer content, an array element or a struct field.

var buffer = ctypes.char.array(10)();

var someCFunction = library.declare("someCFunction", ctypes.default_abi, ctypes.void_t, ctypes.char.ptr);

someCFunction(buffer); // here ctypes.char.array(10)() is converted to ctypes.char.ptr type

Implicit conversion can be tested in the following way:

var myStruct = ctypes.StructType("myStructType", [
  { "v": ctypes.bool }
])();
myStruct.v = 1;
console.log(myStruct.v.toString()); // 'true'

Boolean type

Target Type Source Converted value
ctypes.bool JS boolean src
JS number
(0 or 1)
if src == 0: false
if src == 1: true
var myStruct = ctypes.StructType("myStructType", [
  { "v": ctypes.bool }
])();

myStruct.v = true;
console.log(myStruct.v.toString()); // 'true'
myStruct.v = false;
console.log(myStruct.v.toString()); // 'false'
myStruct.v = 1;
console.log(myStruct.v.toString()); // 'true'
myStruct.v = 0;
console.log(myStruct.v.toString()); // 'false'

myStruct.v = 10;         // throws Error
myStruct.v = "a";        // throws Error

Integer types

Target Type Source Converted value
ctypes.char16_t JS string
(only if its length == 1)
src.charCodeAt(0)
any integer types JS number
(only if fits to the size)
src
JS boolean if src == true: 1
if src == false: 0
var myStruct = ctypes.StructType("myStructType", [
  { "v": ctypes.char16_t }
])();

myStruct.v = 0x41;
console.log(myStruct.v.toString()); // "A"
myStruct.v = true;
console.log(myStruct.v.toString()); // "\x01"
myStruct.v = "X";
console.log(myStruct.v.toString()); // "X"

myStruct.v = "XX";                  // throws Error
var myStruct = ctypes.StructType("myStructType", [
  { "v": ctypes.int16_t }
])();

myStruct.v = 0x41;
console.log(myStruct.v.toString()); // 65
myStruct.v = true;
console.log(myStruct.v.toString()); // 1

myStruct.v = "X";                   // throws Error

Integer/float types are implicitly convertible if any data of source type could be representable in the target type.

Note that the following table does not contain environment dependent types (ctypes.long, etc.).

Target Type Source Type
ctypes.int16_t ctypes.int8_t
ctypes.uint8_t
ctypes.short
ctypes.uint16_t ctypes.uint8_t
ctypes.unsigned_short
ctypes.short ctypes.int8_t
ctypes.uint8_t
ctypes.int16_t
ctypes.unsigned_short ctypes.uint8_t
ctypes.uint16_t
ctypes.int32_t ctypes.int8_t
ctypes.uint8_t
ctypes.int16_t
ctypes.uint16_t
ctypes.short
ctypes.unsigned_short
ctypes.int
ctypes.uint32_t ctypes.uint8_t
ctypes.uint16_t
ctypes.unsigned_short
ctypes.unsigned_int
ctypes.int ctypes.int8_t
ctypes.uint8_t
ctypes.int16_t
ctypes.uint16_t
ctypes.short
ctypes.unsigned_short
ctypes.int32_t
ctypes.unsigned_int ctypes.uint8_t
ctypes.uint16_t
ctypes.unsigned_short
ctypes.uint32_t
ctypes.int64_t ctypes.int8_t
ctypes.uint8_t
ctypes.int16_t
ctypes.uint16_t
ctypes.short
ctypes.unsigned_short
ctypes.int32_t
ctypes.uint32_t
ctypes.int
ctypes.unsigned_int
ctypes.long_long
ctypes.uint64_t ctypes.uint8_t
ctypes.uint16_t
ctypes.unsigned_short
ctypes.uint32_t
ctypes.unsigned_int
ctypes.unsigned_long_long
ctypes.long_long ctypes.int8_t
ctypes.uint8_t
ctypes.int16_t
ctypes.uint16_t
ctypes.short
ctypes.unsigned_short
ctypes.int32_t
ctypes.uint32_t
ctypes.int
ctypes.unsigned_int
ctypes.int64_t
ctypes.unsigned_long_long ctypes.uint8_t
ctypes.uint16_t
ctypes.unsigned_short
ctypes.uint32_t
ctypes.unsigned_int
ctypes.uint64_t
ctypes.float32_t ctypes.int8_t
ctypes.uint8_t
ctypes.int16_t
ctypes.uint16_t
ctypes.short
ctypes.unsigned_short
ctypes.float64_t ctypes.int8_t
ctypes.uint8_t
ctypes.int16_t
ctypes.uint16_t
ctypes.short
ctypes.unsigned_short
ctypes.int32_t
ctypes.uint32_t
ctypes.int
ctypes.unsigned_int
ctypes.float32_t
ctypes.char ctypes.int8_t
ctypes.signed_char ctypes.int8_t
ctypes.unsigned_char ctypes.uint8_t
ctypes.char16_t ctypes.uint8_t
ctypes.uint16_t
ctypes.unsigned_short
var myStruct = ctypes.StructType("myStructType", [
  { "v": ctypes.int16_t }
])();

myStruct.v = ctypes.int8_t(10);
console.log(myStruct.v.toString()); // 10

myStruct.v = ctypes.int32_t(10);    // throws Error

Float types

Target Type Source Converted value
any float types JS number
(only if fits to the size)
src

Pointer types

Target Type Source Converted value
any pointer types null nullptr
ctypes.voidptr_t any pointer types src
any array types src.addressOfElement(0)
ctypes.PointerType(T) ctypes.ArrayType(T) src.addressOfElement(0)
ctypes.ArrayType(T, N) src.addressOfElement(0)
var myStruct = ctypes.StructType("myStructType", [
  { "v": ctypes.int16_t.ptr }
])();

myStruct.v = ctypes.int16_t.array(10)();
console.log(myStruct.v.toString());      // 'ctypes.int16_t.ptr(ctypes.UInt64("0x11d6ff400"))'
myStruct.v = null;
console.log(myStruct.v.toString());      // 'ctypes.int16_t.ptr(ctypes.UInt64("0x0"))'

myStruct.v = ctypes.int32_t.array(10)(); // throws Error

Only in FunctionType argument, the following rules are also applied:

Target Type Source Converted value
ctypes.char.ptr JS string pointer to temporary allocated null-terminated UTF8 string
ctypes.signed_char.ptr
ctypes.unsigned_char.ptr
ctypes.char16.ptr JS string pointer to temporary allocated null-terminated UTF16 string
any pointer types any ArrayBuffer object pointer to the ArrayBuffer
ctypes.voidptr_t any TypedArray/DataView object pointer to the TypedArray/DataView
ctypes.char.ptr
ctypes.int8_t.ptr Int8Array pointer to the Int8Array
ctypes.uint8_t.ptr UInt8Array pointer to the UInt8Array
UIntClamped8Array pointer to the UIntClamped8Array
ctypes.int16_t.ptr Int16Array pointer to the Int16Array
ctypes.uint16_t.ptr UInt16Array pointer to the UInt16Array
ctypes.int32_t.ptr Int32Array pointer to the Int32Array
ctypes.uint32_t.ptr UInt32Array pointer to the UInt32Array
ctypes.float32_t.ptr Float32Array pointer to the Float32Array
ctypes.float64_t.ptr Float64Array pointer to the Float64Array

var myFuncType = ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, [ctypes.int16_t.ptr]);
var myFunc = myFuncType.ptr(function(v) { console.log(v.toString()); });

myFunc(Int16Array([1, 2, 3])); // 'ctypes.int16_t.ptr(ctypes.UInt64("0x103b7fe60"))'
myFunc(Int32Array([1, 2, 3])); // throws Error
var myFuncType = ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, [ctypes.char.ptr]);
var myFunc = myFuncType.ptr(function(v) { console.log(v.toString()); });

myFunc("abcde");               // 'ctypes.char.ptr(ctypes.UInt64("0x101d1d680"))'
myFunc(Int32Array([1, 2, 3])); // 'ctypes.char.ptr(ctypes.UInt64("0x103b7ffe0"))'

Array types

Target Type Source Converted value
ctypes.char.array(N) JS string
(only if UTF8 representation fits to the array)
null-terminated UTF8 string
ctypes.signed_char.array(N)
ctypes.unsigned_char.array(N)
ctypes.char16_t.array(N) JS string
(only if fits to the array)
null-terminated UTF16 string
any array types JS array
(only if array length is same)
convert each element implicitly
any array types any ArrayBuffer object
(only if array length is same in bytes)
copy data
ctypes.int8_t.array(N) Int8Array
(only if array length is same in bytes)
ctypes.uint8_t.array(N) UInt8Array
(only if array length is same in bytes)
UIntClamped8Array
(only if array length is same in bytes)
ctypes.int16_t.array(N) Int16Array
(only if array length is same in bytes)
ctypes.uint16_t.array(N) UInt16Array
(only if array length is same in bytes)
ctypes.int32_t.array(N) Int32Array
(only if array length is same in bytes)
ctypes.uint32_t.array(N) UInt32Array
(only if array length is same in bytes)
ctypes.float32_t.array(N) Float32Array
(only if array length is same in bytes)
ctypes.float64_t.array(N) Float64Array
(only if array length is same in bytes)
var myStruct = ctypes.StructType("myStructType", [
  { "v": ctypes.int16_t.array(5) }
])();

myStruct.v = [1, 2, 3, 4, 5];
console.log(myStruct.v.toString()); // 'ctypes.int16_t.array(5)([0, 0, 0, 0, 0])'
myStruct.v = Int16Array([1, 2, 3, 4, 5]);
console.log(myStruct.v.toString()); // 'ctypes.int16_t.array(5)([1, 2, 3, 4, 5])'

myStruct.v = [1, 2, 3, 4];          // throws Error
var myStruct = ctypes.StructType("myStructType", [
  { "v": ctypes.char.array(5) }
])();

myStruct.v = "abcde";
console.log(myStruct.v.toString()); // 'ctypes.char.array(5)([97, 98, 99, 100, 101])'
myStruct.v = "abc";
console.log(myStruct.v.toString()); // 'ctypes.char.array(5)([97, 98, 99, 0, 0])'

myStruct.v = myStruct.v = "abcdef"; // throws Error

Struct types

JS object can be converted into struct type:

var POINT = ctypes.StructType("POINT", [
  { x: ctypes.int32_t },
  { y: ctypes.int32_t },
]);

var myStruct = ctypes.StructType("myStructType", [
  { "v": POINT }
])();

myStruct.v = {
  x: 10,
  y: 20
};
console.log(myStruct.v.toString()); // 'POINT(10, 20)'

myStruct.v = {
  x: 10
};                                  // throws Error

myStruct.v = {
  x: 10,
  y: 20,
  z: 30
};                                  // throws Error

myStruct.v = {
  x: 10,
  z: 10
};                                  // throws Error
Target Type Source Converted value
any struct types JS object
(Only if the object has properties for all fields and no other properties)
implicitly convert each enumerable property to corresponding field

Explicit convert

In js-ctypes, data could be converted explicitly, when passing to CData constructor:

ctypes.int32_t("123"); // string "123" is parsed as 10-base string

Explicit convert tries implicit convert first, and if it fails, the following rules are applied:

Boolean type

Target Type Source Converted value
ctype.bool JS value ToBoolean(src)
console.log(ctypes.bool("123").toString()); // 'ctypes.bool(true)'
console.log(ctypes.bool("").toString());    // 'ctypes.bool(false)'

Integer types

Target Type Source Converted value
any integer types JS number except -Infinity, Infinity, NaN C-style cast
-Infinity 0
Infinity
NaN
ctypes.Int64 C-style cast
ctypes.UInt64
JS string with base-10 or base-16 string
(only if fits to the size)
parse src as base-10 or base-16 string
console.log(ctypes.int32_t(Infinity).toString());         // 'ctypes.int32_t(0)'
console.log(ctypes.int32_t("0xff").toString()));          // 'ctypes.int32_t(255)'
console.log(ctypes.int32_t(ctypes.Int64(10)).toString()); // 'ctypes.int32_t(10)'

Pointer types

Target Type Source Converted value
any pointer types JS number
(only if fits to the pointer size)
C-style cast
ctypes.Int64
(only if fits to the pointer size)
C-style cast
console.log(ctypes.int32_t.ptr(0xfffffffff).toString()); // 'ctypes.int32_t.ptr(ctypes.UInt64("0xfffffffff"))'

See Also