Hallo,
ich habe eine Wrapper Bibliothek erstellt, mit der man aus der Programmiersprache D auf Firemonkey zugreifen kann [1].
Ein einfaches Beispiel in D sieht dann so aus:
Code:
import delta.core;
import System.Classes, System.UITypes, FMX.Forms, FMX.Types, FMX.Memo;
void main()
{
deltaLibrary.load(`.\views\
Win32\Debug\Project1.dll`);
Application.Initialize;
Application.MainForm = TCustomForm.CreateNew(Application);
Application.MainForm.Caption = "Sample";
auto memo = TMemo.Create(Application.MainForm);
memo.Lines.Add("Hello World!");
memo.Align = TAlignLayout.Client;
memo.Parent = Application.MainForm;
Application.MainForm.Show();
Application.Run();
}
Die Project1.dll ist in Delphi geschrieben und bietet Funktionen um dynamisch Delphi Class Instances anzulegen und deren
Methoden aufzurufen. Das funktioniert soweit gut. Wo ich gerade nicht weiterkomme, ist wenn eine Methode ein Record Argument
hat.
Beispiel TCanvas.DrawLine hat zweimal den Record Type TPointF:
procedure DrawLine(const APt1, APt2: TPointF; const AOpacity: Single); overload;
In meiner
DLL habe ich eine generische Funktion, um Instance Methoden aufzurufen, die als Argumente (Record, Record, Single)
erwarten:
Delphi-Quellcode:
procedure executeInstanceMethodReturnNoneArgsStructStructFloat(
const Reference: Integer;
const AName: PAnsiChar; Reference2, Reference3: Integer; s: Single);
stdcall;
begin
// Was muss ich hier machen?
executeInstanceMethod(Reference,
string(AName), [???]);
end;
function executeInstanceMethod(
const Reference: Integer;
const AName:
string;
const Args:
array of TValue): TValue;
var
context: TRttiContext;
instType: TRttiInstanceType;
obj: TObject;
begin
context := TRttiContext.Create;
try
try
obj := TObject(Reference);
instType := (context.GetType(obj.ClassType)
as TRttiInstanceType);
result := instType.GetMethod(AName).Invoke(obj, Args);
except
on E:
Exception do
writeln(E.ClassName + '
error raised, with message : ' + E.
Message);
end;
finally
context.Free;
end;
end;
(Das Argument Reference hat die Klassen Referenz zu TCanvas, AName beinhaltet den Methoden Namen DrawLine, danach kommen die eigentlichen
Argument für die DrawLine Methode)
Aus meinem Programm möchte ich dann beim Aufruf von
"executeInstanceMethodReturnNoneArgsStructStructFl oat" Referenzen auf Records (D Strukturen die binär kompatibel sind) übergeben.
In der Funktion "executeInstanceMethodReturnNoneArgsStructStructFl oat" sollen dann diese Record Referenzen umgewandelt
werden, in etwas mit der dann am Ende die TRttiMethod.Invoke Methode etwas anfangen kann.
Ist das technisch überhaupt machbar und wenn es gehen sollte, wie könnte das Coding dafür ungefähr aussehen?
Viele Grüße
André
[1]
https://github.com/andre2007/delta-fmx-10-2-1