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: falseif 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: 1if 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"))'
