Hi,
wir müssen ein etwas betagtes Delphi Parametrierprogramm in eine neue Version umsetzen.
Beim erstellen des Pflichtenheftes ergab sich, dass eigentlich nur Grundfunktionalität und die Funktionen von ca 100 Fenstern erhalten bleiben müssen.
Da wir, hier im Hause, nur sehr wenige Delphi (Objectpascal) Programmierer sind (2) aber jede Menge C++ und C# Leute zur Verfügung stehen haben wir uns Gedanken darüber gemacht einen Teil des Codes in C++ oder C#
DLL's auszulagern.
Alles neu in C++ oder C# geht nicht (Kostengründe und hab auch keine Lust am eigenen Stuhl zu sägen).
Meine Fragen hierzu:
1.) Sind, von Delphi (
Win32) aus, C++ und C#
DLL's zugänglich. Von C#
DLL's hab ich gehört die wären unter Delphi (
Win32) nicht (oder nicht einfach) zugänglich.
2.) Wir beabsichtigen mittels Callback komplette Funktionsgruppen, so z.B. einen Parser auszulagern.
Aufruf mittels Prozedur mit Callbackadresse und einer Liste mit Parametern.
Die eigentlich Callbackroutine nimmt dann die Ergebnisse entgegen.
3.) Wie mache ich das mit der Übergabe? Wir haben Massenweise Beschreibungen unserer Geräte die in Strings oder Stringlists abliegen. Kann ich eine Stringlist an eine C++ oder C#
Dll übergeben und eine Stringlist als Funktionsergebnis wieder zurück erhalten?
Beispiel:
Übergabeliste:
R1Neab=Aus
R1Newi=wie vor Abschaltung
Rückgabe:
05 A7 3E ..........................
immer in Gruppen zu je 32 Bytes
Ausprobiert haben wir das Ganze schon mit reinen Delphi
DLL's. Callback funktioniert.
Unser Problem wie realisiere ich die Parameterübergabe mit reinen Pointern (habe bis jetzt immer statische Variablen genutzt) und wie kriege ich die Parameterübergabe in Listen hin.
Unsere Muster
DLL. Habe damit einen Durchschnitt aus einer Liste berechnet (Nur Average wird genutzt):
Delphi-Quellcode:
uses
SysUtils,
Classes;
{$R *.res}
procedure Average(cb: Pointer;a:
array of integer);
stdcall;
//das wäre die API
var
i: Integer;j:double;
CallBack:
function(i: double): Boolean;
stdcall;
begin
if Assigned(cb)
then
begin
@CallBack := cb;
j:=0;
for i := 0
to length(a)-1
do j:=j+a[i];
j:= j / length(a);
CallBack(j);
end;
end;
procedure DoSomething(cb: Pointer;a:
array of integer);
stdcall;
//das wäre die API
var
i: Integer;
CallBack:
function(i: integer): Boolean;
stdcall;
begin
if Assigned(cb)
then
begin
@CallBack := cb;
for i := 0
to 9
do
CallBack(a[i]);
end;
end;
exports
DoSomething, Average;
begin
end.
Hier das zugehörige Programm das die
DLL nutzt:
Delphi-Quellcode:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 =
class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
function CallBack1(i: integer): Boolean;
stdcall;
end;
procedure DoSomething(cb: Pointer;a:
array of integer);
stdcall;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure DoSomething(cb: Pointer;a:
array of integer);
stdcall;
external '
Project1.dll';
procedure Average(cb: Pointer;a:
array of integer);
stdcall;
external '
Project1.dll';
function TForm1.CallBack1(i: integer): Boolean;
stdcall;
begin
ShowMessage(IntToStr(i));
end;
function CallBack2(i: double): Boolean;
stdcall;
begin
ShowMessage(floatToStr(i));
end;
procedure TForm1.Button1Click(Sender: TObject);
var a:
array[1..10]
of integer;n,j,i:integer;
begin
For n:=1
to 10
do a[n]:=n;
//n*2;
Average(@CallBack2,a);
// aufruf mit der callback funtion als pointer
end;
end.
Zunächst möchte ich, als Übergabe, Pointer nutzen und dann die
DLL in C++ umsetzen.
Vielleicht hat jemand auch noch eine andere Idee wie man Code aufsplitten kann?
(Dies sind unsere ersten Versuche mit
DLL's und im speziellen mit Callback Funktionen, also nicht sauer sein wenn sich dort banale Fehler eingeschlichen haben)
Ich hoffe ihr könnt uns bzw mir weiterhelfen.
Grüsse
Rainer