Skip to content

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:

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++)

C++ library code
#include <windows.h>

extern "C" wchar_t* __declspec(dllexport) _cdecl GetCurrentUsername(wchar_t* data)
{
    DWORD i = 256;
    GetUserNameW(data, &i);
    return data;
}
TypeScript/JavaScript code
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++)

C++ library code
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");
TypeScript/JavaScript code
application.on('custom-message', (message) => {
    if (message.id === 0x01) {
        //handle message.data
    } else if (message.id === 0x02) {
        //handle message.data 
    }
});