Writing Plugins¶
Simba scripts can be extended with plugins. Plugins are libraries (dll/so/dylib) which can be written in virtually every low-level language.
Note
For 32bit the cdecl calling convention is used for methods plugin related. Otherwise the default systems calling convention is used.
Importing functions¶
To import functions the following methods must be exported to provide information to Simba.
function GetFunctionInfo(Index: Integer; var Address: Pointer; var Header: PChar): Integer; cdecl;
function GetFunctionCount: Integer; cdecl;
Note
native;
to the header cause parameters and result passed in the Lape wrapper format.The Lape wrapper format is procedure(const Params: PParamArray; const Result: Pointer)
Importing types¶
To import types the following methods must be exported to provide information to Simba.
function GetTypeInfo(Index: Integer; var Name: PChar; var Str: PChar): Integer; cdecl;
function GetTypeCount: Integer; cdecl;
Note
These methods are imported before GetFunctionInfo & GetFunctionCount so these types will be available when adding functions.
Importing code¶
Code can be imported in the script with the following methods exported.
procedure GetCode(var Code: PChar); cdecl;
function GetCodeLength: Integer; cdecl;
RegisterSimbaPlugin¶
A plugin can export RegisterSimbaPlugin which provides access to various Simba’s infomation & methods.
procedure RegisterSimbaPlugin(Infomation: PSimbaInfomation; Methods: PSimbaMethods); cdecl;
These pointers are provided to these structures:
TSimbaInfomation = packed record
SimbaVersion: Integer;
SimbaMajor: Integer;
FileName: PChar;
Compiler: Pointer;
end;
TSimbaMethods = packed record
RunOnMainThread: procedure(Method: TMainThreadMethod; Data: Pointer = nil); cdecl;
GetMem: function(Size: NativeUInt): Pointer; cdecl;
FreeMem: function(P: Pointer): NativeUInt; cdecl;
AllocMem: function(Size: NativeUInt): Pointer; cdecl;
ReAllocMem: function(var P: Pointer; Size: NativeUInt): Pointer; cdecl;
MemSize: function(P: Pointer): NativeUInt; cdecl;
RaiseException: procedure(Message: PChar); cdecl;
GetTypeInfo: function(Compiler: Pointer; Typ: PChar): Pointer; cdecl;
GetTypeInfoSize: function(TypeInfo: Pointer): NativeInt; cdecl;
GetTypeInfoFieldOffset: function(TypeInfo: Pointer; FieldName: PChar): NativeInt; cdecl;
AllocateRawArray: function(ElementSize, Len: NativeInt): Pointer; cdecl;
ReAllocateRawArray: procedure(var Arr: Pointer; ElementSize, NewLen: NativeInt); cdecl;
AllocateArray: function(TypeInfo: Pointer; Len: NativeInt): Pointer; cdecl;
AllocateString: function(Data: PChar): Pointer; cdecl;
AllocateUnicodeString: function(Data: PUnicodeChar): Pointer; cdecl;
SetArrayLength: procedure(TypeInfo: Pointer; var AVar: Pointer; NewLen: NativeInt); cdecl;
GetArrayLength: function(AVar: Pointer): NativeInt; cdecl;
ExternalImage_Create: function(AutoResize: Boolean): Pointer; cdecl;
ExternalImage_SetMemory: procedure(Img: Pointer; Data: PColorBGRA; AWidth, AHeight: Integer); cdecl;
ExternalImage_Resize: procedure(Img: Pointer; NewWidth, NewHeight: Integer); cdecl;
ExternalImage_SetUserData: procedure(Img: Pointer; UserData: Pointer); cdecl;
ExternalImage_GetUserData: function(Img: Pointer): Pointer; cdecl;
end;
See the Example C++ plugin to see how TypeInfo is used to allocate custom records & arrays.
Note
Scripts are not ran on the process main thread so RunOnMainThread is available for creating forms, installing windows hooks that must be executed on the main thread.