clib
The clib
module exposes Blade capabilities to interact with C
shared libraries. The workflow follows a simple approach.
- Load the library
- Define the function schematics
- Call the function.
That simple!
For example, the following code
dirname()
andcos()
function from the standard C library on a Unix machine (Linux, OSX, FreeBSD etc).
# Import clib
import clib
# 1. Load 'libc' shared module available on Unix systems
var lib = clib.load('libc')
# 2. Declare the functions
var dirname = lib.define('dirname', clib.char_ptr, clib.char_ptr)
var cos = lib.define('cos', clib.double, clib.double) # this may not work on linux
# 3. Call the functions
echo dirname('/path/to/my/file.ext')
echo cos(23)
# Close the library(this is a good practice, but not required)
lib.close()
The first argument to a definition is the name of the function. The second is its return type. If the function takes parameters, the parameter types follow immediately. (See below for a list of the available types.)
NOT YET SUPPORTED:
- Variadic functions
Fields
- clib.void ➝ ptr
- C void type
- clib.bool ➝ ptr
- C bool type
- clib.uint8_t ➝ ptr
- C uint8_t type
- clib.int8_t ➝ ptr
- C int8_t type
- clib.byte ➝ ptr
- C byte type
- clib.ubyte ➝ ptr
- C ubyte type
- clib.uint16_t ➝ ptr
- C uint16_t type
- clib.int16_t ➝ ptr
- C int16_t type
- clib.uint32_t ➝ ptr
- C uint32_t type
- clib.int32_t ➝ ptr
- C int32_t type
- clib.uint64_t ➝ ptr
- C uint64_t type
- clib.int64_t ➝ ptr
- C int64_t type
- clib.ssize_t ➝ ptr
- C ssize_t type
- clib.float ➝ ptr
- C float type
- clib.double ➝ ptr
- C double type
- clib.uchar ➝ ptr
- C uchar type
- clib.char ➝ ptr
- C char type
- clib.ushort ➝ ptr
- C ushort type
- clib.short ➝ ptr
- C short type
- clib.uint ➝ ptr
- C uint type
- clib.int ➝ ptr
- C int type
- clib.ulong ➝ ptr
- C ulong type
- clib.long ➝ ptr
- C long type
- clib.size_t ➝ ptr
- C size_t type
- clib.long_double ➝ ptr
- C long_double type
- clib.char_ptr ➝ ptr
- C char_ptr type
- clib.uchar_ptr ➝ ptr
- C uchar_ptr type
- clib.ptr ➝ ptr
- C ptr type
- clib.function ➝ ptr
- C closure/callback type
Functions
- clib.load(name)
-
Loads a new C shared library pointed to by name. Name must be a relative path, absolute path or the name of a system library. If the system shared library extension is omitted in the name, it will be automatically added.
- @params:
- string name
- @returns: CLib
- @params:
- clib.new(type, ...)
-
Creates a new C value for the specified clib type with the given values.
- @params:
- clib_type type
- any... values
- @returns: bytes
- @params:
- clib.get(type, data)
-
Returns the data contained in a C type type encoded in the data. The data should either be an output of
clib.new()
or a call to a function returning one of struct, union or array.For structures created with
named_struct()
, a dictionary will automatically be returned with the values mapped to the names of the structure elements.- @params:
- clib_type type
- string|bytes data
- @returns: list|dictionary
- @params:
- clib.get_ptr_index(pointer, type, index)
-
get_ptr_index(pointer: ptr, type: clib_type, index: number)
Get the value at the given index of a pointer based on the given CLib type.
- @params:
- ptr pointer
- clib_type type
- number index
- @returns: any
- @params:
- clib.set_ptr_index(pointer, type, index, value)
-
Sets the value at the given index of a pointer based on the given CLib type to the given value.
- @params:
- ptr pointer
- clib_type type
- number index
- any value
- @returns: any
- @params:
- clib.function_handle(handle, return_type, ...)
-
Defines a new C function from an existing handle and return type.
- When there are no more argument, it is declared that the function takes no argument.
define()
expects a list of the argument/parameter types as expected by the function.
E.g.
function_handle(my_ptr, int, int, ptr)
Corresponds to the C declaration:
int (*my_ptr)(int a, void *b);
- @params:
- ptr handle
- clib_type return_type
- clib_type... arg_types
- @returns: function
- clib.create_callback(closure, return_type, ...)
-
Creates a callback to be passed to C functions expecting a callback.
For example, imagine a C function defined as below:
void ex_puts(const char *name, void (*fn)(char *req, char *res));
To pass the callback (second parameter) to this function, you'll need to wrap a blade function with
create_callback()
to properly define the callback return type and parameters.The above function can be defined as:
var fn lib.define('ex_puts', clib.void, clib.char_ptr, clib.function)
To call this function and pass a Blade function that can be called when C triggers the callback, the second argument to the function will need to be wrapped in
create_callback()
. Thus, the above function can be called like this:fn( 'Blade Callbacks', clib.create_callback( @(req, res) { echo 'Request is: ' + req echo 'Response is: ' + res }, clib.void, # The return type of the callback clib.char_ptr, clib.char_ptr # the parameters of the callback ) )
NOTE: A callback can only be passed to a parameter previously defined as function.
- @params:
- function closure
- clib_type return_type
- clib_type... types
- @returns: clib_callback
- @params:
- clib.struct(...)
-
Returns a type that can be used to declare structs. To create or read value for the struct you need to use the
new()
andget()
functions respectively. Alternatively, you may use thepack()
andunpack()
function in thestruct
module respectively.@notes:
- This function can also be used to define a C union or array.
- @params:
- any... type
- @returns: type
- clib.named_struct(types)
-
Returns a type that can be used to declare structs based on the named types. The function works well with the
get()
function because it automatically assigns the name of the struct elements when getting the value.To create or read value for the struct you need to use the
new()
andget()
functions respectively. Alternatively, you may use thepack()
andunpack()
function in thestruct
module respectively.@notes:
- This function can also be used to define a C union or array.
- @params:
- dictionary types
- @returns: type
Classes
- class Clib
-
class CLib provides an interface for interacting with C shared modules.
- .Clib(name) ➝ Constructor
-
clib.Clib constructor
@notes:
- The name should follow the same practice outlined in
load()
.
- @params:
- string? name
- The name should follow the same practice outlined in
- .load(name)
-
Loads a new C shared library pointed to by name. Name must be a relative path, absolute path or the name of a system library. If the system shared library extension is omitted in the name, it will be automatically added except on Linux machines.
- @params:
- string name
- @params:
- .close()
-
Closes the handle to the shared library.
- .function(name)
-
Retrieves the handle to a specific function in the shared library.
- @params:
- string name
- @returns: ptr
- @params:
- .define(name, return_type, ...)
-
Defines a new C function with the given name and return type.
- When there are no more argument, it is declared that the function takes no argument.
define()
expects a list of the argument/parameter types as expected by the function.
E.g.
define('myfunc', int, int, ptr)
Corresponds to the C declaration:
int myfunc(int a, voidb);
- @params:
- string name
- clib_type return_type
- clib_type... types
- @returns: function
- .get_pointer()
-
Returns a pointer to the underlying module.
- @returns: ptr