Custom extensibility
It's possible to extend a Miletus application with further custom functionality via the usage of shared libraries. Shared libraries per platforms are:
- Windows:
dll
- macOS:
dylib
- Linux:
so
- Raspberry Pi:
so
To extend an application the following methods can be used:
loadLibrary(path)
unloadLibrary(path)
callLibProc(path, proc[, data])
callLibFunc(path, func[, data])
Load a library to be used and unload it when it's no longer needed. When a library is loaded procedures and functions can be executed from it.
Executing procedures
Procedures don't have a return value.
There is an optional data
parameter to enable sending some data to the library. In the library implementation this optional parameter is an UTF-16 encoded string pointer.
Example
A shared library written in C++ for Windows would have a wchar_t
or char16_t
parameter. For Linux and macOS it would be char16_t
.
Executing functions
Functions return with a string. In the library implementation the return value is a UTF-16 encoded string pointer.
There is an optional data
parameter to enable sending some data to the library. In the library implementation this optional parameter is an UTF-16 encoded string pointer.
Custom callbacks
To allow sending custom messages to the application at any given time, implement the RegisterCallback
function in the shared library.
RegisterCallback
is a fixed name that the shell application will be looking for in the loaded library. Only the last loaded library that contains RegisterCallback
will execute callbacks.
Examples
Getting username from DLL (C++)
#include <windows.h>
extern "C" wchar_t* __declspec(dllexport) _cdecl GetCurrentUsername(wchar_t* data)
{
DWORD i = 256;
GetUserNameW(data, &i);
return data;
}
import { application } from 'miletus';
...
let lib = 'path_to_my_dll';
let b = await application.loadLibrary(lib);
if (b) {
let user = ' '.repeat(256);
let result = await application.callLibFunc(lib, '_GetCurrentUsername', user);
console.log('Current user: ' + result);
application.unloadLibrary(lib);
}
RegisterCallback implementation in a DLL (C++)
typedef void (*PTR_CALLBACK)(int, wchar_t*);
PTR_CALLBACK my_callback;
extern "C" void __declspec(dllexport) _cdecl RegisterCallback(void (callback)(int, wchar_t*))
{
my_callback = callback;
}
//...
//At a later point whenever a message needs to be sent back
my_callback(0x01, (wchar_t*) L"My message");