Umajin has an interface that allows integrating native code into your project. This is supported fully for desktop platforms (Windows and Mac), where you can use native libraries in Umajin Editor, Umajin Lite or a published app. We also support iOS, but due to Apple restrictions, native libraries can only be tested and used in published app builds on iOS..
It must be possible to create a 64 bit DLL or Dynamic Library (dylib) with a C-style API. For iOS, you will create a full Framework.
Writing the native library
Your native library must implement the following C functions and export them to the DLL or Dylib.
const char* umajinGetIdentifier(void); const char* umajinProcess(long long tag, const char* payload); const char* umajinPoll(long long tag, long long timestamp);
umajinGetIdentifier just returns an internal name for the library. This is checked for uniqueness.
umajinProcess is the interface for editor/JS to call into the library.
umajinPoll is called every frame for the library to send data to the project JS, if it has any; i.e. asynchronous events or responses.
Installing the native library
Once you have created your native library, place the files in the Umajin Project folder as follows:
- Windows: Place your <name>.dll in /manifest/win/bin
- Mac: Place your lib<name>.dylib in /manifest/osx/bin
- iOS: Place your entire <name>.framework folder in /manifest/ios/Frameworks
You may need to create these folders if they do not already exist.
Note that while you may be able to use other folders, these are the standard folders that will work correctly in all situations, including when the app is “published” as a standalone application. In such standalone apps the files will be moved into appropriate places within the package. On Mac, they will be placed in the Contents/Frameworks folder in the .app folder.
Loading the library
From Javascript, call registerExternalFunction() with the library name. Umajin will work out what to load.
libraryId = registerExternalFunction( 'myLibrary', 'onLibData', 'onLibError');
The library will be loaded from an appropriate filename and place depending on the type of application and operating system.
It will return the same name as you pass in, which you should save in a global variable for use later.
If the library could not be loaded, it will return blank; the onLibError event will also be called.
Note that all the 3 functions must be present with correct names for loading to succeed.
The expected filename is:
- myLibrary.dll on Windows
- libMyLibrary.dylib on MacOS. Note the expected “lib” prefix for MacOS.
- myLibrary.framework (folder) on iOS.
If you want to load a filename that doesn’t have the standard extension or prefix, you can do so by specifying the extension. You can also supply a path, in which case Umajin will use that directly.
For Umajin Editor versions prior to 4.0.4, it’s necessary to work out the path in detail based on OS and application mode.
var libFolder = getGlobal('project_path') + '/manifest'; var platformFolder = ''; if (getGlobal('os').toLowerCase().includes('windows')) { platformFolder = '/win/bin/'; } else { platformFolder = '/osx/bin/'; } if (getGlobal('app_mode') == 0) { // Standalone app, path is internally resolved libFolder = ''; platformFolder = ''; } var libPath = libFolder + platformFolder + 'UmajinTestLib'; libraryId = registerExternalFunction( libPath, 'onLibData', 'onLibError');
Using the library
Once successfully loaded, you can send data to the library using:
var result = externalFunctionProcess(libraryId , data);
This function can return data immediately.
If the library needs to send data back to the JS at another time (e.g. an asynchronous response to an earlier request), then it can return data when the umajinPoll() function is called. This will result in your onLibData function being called (that was registered with registerExternalFunction).
function onLibData(data) { }