Using shared libraries

A Shared library is a file containing executable functions, usually written in a low level language like C, compiled and optimized into machine code for a specific device. The advantages of using shared libraries include fast execution of complex algorithms, and the ability to directly access a device's hardware and operating system. The following Javascript will load a shared library ... library_object = new dev.sys.Library ('filename');

If the specified library file is found inside the app, it will be copied into the application's data folder for the operating system to load, otherwise the operating system will search the standard paths for the file. If no filename extension is given, the standard extension for shared libraries on that operating system will be appended. If the library cannot be found or loaded, then the library object will be Null.

Library functions can be imported into JavaScript using C style function declarations. Supported C types are: void, bool, char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, float, double, and all their respective pointers, with long being 64 bits. library_object.import ("c_type function_name (c_type param1, c_type param2, ...)");

Any number of functions can be imported at the same time. A template literal is useful for C code spanning multiple lines. library_object.import (` c_type function_name_1 (c_type param1, c_type param2, ...); c_type function_name_2 (c_type param1, c_type param2, ...); ... `);

After being imported, a library function can be called directly from Javascript. Values passed into the function will be converted into their respective C types. Objects will be passed in as pointers. Typed arrays will point to their array data. Return values are also converted, with char * returned as a String. library_object.function_name (value1, value2, ... );

32 bit Windows apps use the __cdecl calling convention with all arguments passed in reverse order on the stack. Windows API functions use the __stdcall convention which must be specified in the function declaration.

Android uses the soft-fp calling convention, which passes floating point values the same way as other arguments, in R0 to R3 first then on the stack.

Linux uses the AMD x64 calling convention, which passes arguments in the 64 bit registers and SSE floating point registers before using the stack.

If your function declaration does not match the actual shared library function and calling convention, will likely crash.

Example 1

Consider a simple C function compiled into a Windows library called echo.dll... EXPORT char *EchoString (char *string){ return string;}

This function could be called from JavaScript using... var lib = new dev.sys.Library ('echo'); lib.import ('char *EchoString (char *string);'); console.log (lib.EchoString ('Hello world'));

In other operating systems, the libary might be called and the EXPORT keyword might not be needed, but the JavaScript to call the function would be the same.

Example 2

Consider two C functions compiled into an Android library called double Multiply (double a, double b){ return a * b;} double Divide (double a, double b){ return a / b;}

This function could be called from JavaScript using... var lib = new dev.sys.Library ('math'); lib.import (` double Multiply (double a, double b); double Divide (double a, double b); `); console.log (lib.Multiply (911, 2356));

Example - Win32 API call

An app's window title can be directly set using dev.sys.Windows.title, but this example changes the window title by calling the SetWindowText function in the Win32 API. var hwnd = dev.sys.Windows.hwnd; var lib = new dev.sys.Library ('User32.dll'); lib.import ("int __stdcall SetWindowTextA (void *hwnd, char *name)"); lib.SetWindowTextA (hwnd, "New title");