Custom extensibility for your Miletus application
How it works?
procedure MyProcedureWithParameter(AData: PChar); cdecl; procedure MyProcedureWithoutParameter; cdecl; function MyFunctionWithParameter(AData: PChar): PChar; cdecl; function MyFunctionWithoutParameter: PChar; cdecl;
And the corresponding promises to execute these methods are:
//Resolves with nil in case of await() function ExecProc(ALibraryPath: string; AProc: string; AData: string): TJSPromise; function ExecProc(ALibraryPath: string; AProc: string): TJSPromise; //Resolves with a string in case of await() function ExecFunc(ALibraryPath: string; AFunc: string; AData: string): TJSPromise; function ExecFunc(ALibraryPath: string; AFunc: string): TJSPromise;
type TCallback = procedure(AMessageID: Integer; AData: PChar); cdecl; var MyCallback: TCallBack; const MYID = 123; procedure RegisterCallback(AFunction: Pointer); cdecl; begin @MyCallback := AFunction; end; procedure MyProcedure; cdecl; begin //Do something and call MyCallback MyCallback(MYID, '{"Name": "My data", "Value": "This is my JSON formatted data"}'); end;
To capture the messages sent via the callback, use the MiletusCommunication.OnCustomMessage event.
And of course let’s not forget that you can load a library by calling LoadLibrary(ALibraryPath: string) and unload it by UnloadLibrary(ALibraryPath). With all the puzzle pieces layed out, let’s see how to arrange them into a nice picture.
Let’s see an example
library DemoLib; uses System.SysUtils, System.Classes, Winapi.Windows; {$R *.res} function GetCurrentUsername: PChar; cdecl; var buf: array[0..255] of Char; bufsize: DWORD; begin bufsize := SizeOf(buf); GetUserName(buf, bufsize); Result := buf; end; exports GetCurrentUsername; begin end.
The next step is to use this newly created library from our Miletus application. To keep the application simple, we’ll add a TWebLabel and use that to greet the user when the application starts.
[async] procedure MiletusFormCreate(Sender: TObject);
procedure TForm1.MiletusFormCreate(Sender: TObject); var b: Boolean; user: string; const LIBPATH = 'pathtoDemoLib.dll'; begin b := Await(Boolean, LoadLibrary(LIBPATH)); if b then begin user := Await(string, ExecFunc(LIBPATH, 'GetCurrentUsername')); WebLabel1.Caption := 'Hello, ' + user + '!'; UnloadLibrary(LIBPATH); end; end;
There is no next step, it was simple as that. The result of this as a running application compared to our design-time view:
We hope this gives you many ideas for your current and future Miletus applications. We are curious to see what use cases you come up with!