In this example, we show how to use C structs and pointers with js-ctypes.
Declaring a js-ctypes struct matching a C struct
If we have a C structure like this:
struct st_t { void *self; char *str; size_t buff_size; int i; float f; char c; };
we can use it in JavaScript by writing something like this:
var st_t = new ctypes.StructType("st_t", [ { "self": ctypes.PointerType(ctypes.void_t) }, { "str": ctypes.PointerType(ctypes.char) }, { "buff_size": ctypes.size_t }, { "i": ctypes.int }, { "f": ctypes.float }, { "c": ctypes.char } ]);
Here we are using the StructType()
factory method of the ctypes object to create a CType
object that represents the C struct named st_t
. The first parameter of this method is the name of the type, which corresponds to the name of the C struct. The second parameter is an array of field descriptors. Each field descriptor contains the name and field type of the corresponding field of the C struct. The call to StructType()
returns a CType
object, and we then apply the new
operator to it to create a specific instance of this newly defined type - a JavaScript representation of the C struct.
Using C strings with js-ctypes
A pointer to char in JavaScript is declared as follows:
var str = ctypes.PointerType(ctypes.char);
Now imagine you call a C function that returns a C string and you want to modify the contents of this string. In the js-ctypes context, you can only operate on buffers of known capacity. Therefore, the size of the buffer must be specified. Additionally, the js-ctypes pointer must be casted to reflect the size of the buffer:
var ptr = ctypes.cast( str, ctypes.ArrayType( ctypes.char, buff_size ).ptr );
Here buff_size is of type ctypes.size_t.
Once we have a ctypes char pointer that points to a buffer of known size, we modiify the contents of the memory block as follows:
ptr.contents = String("Hello world from JavaScript!!!");
String() adds the '\0' character.
References
This example is based on code found here.