![]() |
Funktionen in DLL auslagern! Übergabe der Parameter!
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:
Hier das zugehörige Programm das die DLL nutzt:
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.
Delphi-Quellcode:
Zunächst möchte ich, als Übergabe, Pointer nutzen und dann die DLL in C++ umsetzen.
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. 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 |
Re: Funktionen in DLL auslagern! Übergabe der Parameter!
DLL's mit C# geht -glaube ich- nicht.
Wir haben uns für COM entschieden: Die Hauptanwendung ist in Delphi, benötigt aber (auch visuelle) Plugins. |
Re: Funktionen in DLL auslagern! Übergabe der Parameter!
Zitat:
Zitat:
Zitat:
|
Re: Funktionen in DLL auslagern! Übergabe der Parameter!
Moin,
imho gibt es keine Probleme in C++ DLL's zu schreiben, die du in Delphi einbindest. Das Auslagern von Klassen in die DLL und dann diese im eigenen Programm zu nutzen geht aber nicht so weit ich weis. Fenster könnnen jedoch aus der Dll heraus angezeigt werden. Ob das so gut ist kann ich nicht sagen, hängt von eurer Anwendung ab. Zu C# kann ich leider nichts sagen, habe noch keine Dll die in C# geproggt wurde benutzt. Soweit ich das mitbekommen habe benutzt C# doch recht konsequent den Klassenansatz. In wie weit man da überhaupt Funktionen ohne Klassenansatz und DLL's schreiben kann weis ich schlicht und ergreifend nicht. Deine beiden Beispielfunktionen sollten aber wohl ohne Probleme realisierbar sein. Gruß oki |
Re: Funktionen in DLL auslagern! Übergabe der Parameter!
Hallo R2009.
Also bei Verwendung von Win32 und Delphi, C, C++ würde ich folgende API verwenden.
Delphi-Quellcode:
Damit ist mit einer einzigen Funktion, die Übergabe aller möglichen Win32 Datentypen, Structuren etc. möglich.TCallBackProcedure = function(ptrData: Pointer; cbData: LongInt): LongBool; stdcall; function Generic(cbProc: Pointer; ptrData: Pointer; cbData: LongInt): LongBool; stdcall; Hier ein Beispiel wie, über eine Struct, array of integer, über die API ausgetauscht werden kann.
Delphi-Quellcode:
Es müssen vorher nur in einem Pflichtenheft, die ID's für bestimmte Datenstrukturen festgelegt werden.
type
TGenericData = packed record DataID : LongInt; //-- zB. DataID = 1 = array of integer Daten usw. ArrayOfLongInt : ^LongInt; //-- Pointer auf die ersten 4 Byte des ersten Datensatzes LengthArrayOfLongInt : Longint; //-- Wievile Datensätze sind vorhanden end; PGenericData = ^TGenericData; Hier können je nach Bedarf ganz unterschiedliche Ansätze verwirklicht werden. Wichtig ist nur, dass Win32-API Datentypen und Strukturen zum Einsatz kommen. lg. Astat |
Re: Funktionen in DLL auslagern! Übergabe der Parameter!
DLLs in C# müßten doc auch gehn?
Insgesammt muß man sich nur kompatible Schnittstellen überlegen. COM wäre ein Weg und Interfaces allgemein, auch "normale" Prozeduren/Funktionen müßten gehn. Aber insgesamt muß man sich vorallem auf gleiche/kompatible Typen für seine Schnittstellen einigen. Also fallen schonmal AnsiString, UnicodeString und dynamische Arrays weg, es sei denn man implementiert auf C-Seite entsprechende Verwaltungsmethoden. Der WideString läßt sich gut verwenden und PChar sowieso. |
Re: Funktionen in DLL auslagern! Übergabe der Parameter!
Zitat:
dahingehend umsetzen. Ansonsten sollte man sich Gedanken machen, ob man nicht gleich alles in Java oder .Net entwickeln soll. Ich halte zwar absolut nichts davon, aber die Masse geht halt sehr oft ganz eigenartige Wege!?? Folgende Vorgehensweisen sind sehr beliebt. COM, DCOM, RPC ist Gut! Win32-API DLL's sind Böse, diese müssen weg, am besten durch Webservices ersetzen. Die nun fehlenden Libraries werden am besten durch .net Dll ersetzt, diese kann man dann schön Assemblies nennen und man ist wieder "up to date". Sehr beliebt ist auch die Verwendung von Zip komprimierten Ordnern, die man dann *.jar nennt. Alles was nach win32 API Strukturen aussieht, muss krampfhaft in XML gegossen werden. Native Compilersprachen sind Böse, da sehr oft nicht Plattform unabhängig. .net und Java sind gut weil deren Plattform Unabhängigkeit, so schön mit JNI und mit nachträglich doch notwendigen Win32-API Implementierungen, zerstört werden kann. Plötzlich sind COM, DCOM, RPC auch böse? Sockets sind Böse, und dürfen nur unter vorgehaltener Hand erwähnt werden. Versendet man aber XML über Sockets, darf man wieder ohne Probleme darüber reden, natürlich sagt man dann nicht Sockets, diese haben sich auf wunderbare Weise in Webservices, SOAP-Requests, HTTP-Posts und Gets verwandelt. Oh mein Gott, hat das jetzt gut getan!! Also bis zu meinem nächsten Anfall. lg. Astat |
Re: Funktionen in DLL auslagern! Übergabe der Parameter!
Zitat:
Zitat:
Wenn ich natürlich Performance benötige und Zeit habe, dann sollte man natürlich die o.g. Dogmen über den Haufen werfen und von Vorne anfangen. Diese Zeit habe ich aber bedauerlicherweise nicht. |
Re: Funktionen in DLL auslagern! Übergabe der Parameter!
Meiner Erfahrung nach sollte man folgende Dinge vermeiden.
Es geht dabei weniger um Technik als vielmehr um Psychologie und Zusammenarbeit. * keine "Kernkompetenzen" auslagern wenn man Dinge auslagert, die den Kern des Programms ausmachen, gibt man das wichtigste Wissen aus der Hand. Ausserdem dauert es länger einem anderen Programmierer etwas zu erklären, als es selbst umzusetzen. Sollte der Programmierer dieser ausgelagerten Teile das Unternehmen verlassen stehst du "ohne Hosen" da. Du möchtest den Code nicht erben (denn du bist in der Programmiersprache nicht zu Hause) und andere haben auch keine Lust sich mit dem halblebigen Code auseinanderzusetzen. * nichts auslagern, was später öfters angepasst werden muss Ein C#-Programmierer, der für dich ein kleines Stückchen Software schreibt, betrachtet das nur als lästiges Übel. Er wendet sich möglichst schnell wieder den interessanten Sachen zu. Wenn du alle paar Wochen auf der Matte stehst und eine Änderung/Erweiterung brauchst, werden selbst gute Kumpels genervt sein. Und noch eine allgemeine Warnung. Ich habe selbst schon öfters mit diesen ausgelagerten Softwareteilen zu tun gehabt und jedes Mal war das Egebnis schlecht. Beispiel 1: ein Delphiprogramm soll von SAP Daten übernehmen wobei eine C/C++ DLL die Daten von SAP auslesen soll. Folge: es war jede Menge Kommunikation zwischen mir und dem C-Programmierer nötig; in der Zeit hätte ich es selber auch geschafft. Aber ich konnte kein Know-How über SAP sammeln. Inzwischen wurde der Programmierer gekündigt und die DLL ist vom Konzept ein Schrotthaufen geworden, weil auch noch andere darin rumgerührt haben (Copy, Paste und leicht abändern). Beispiel 2: eine C/C++ - DLL steuert Drucker, Meßgeräte und eine SPS an. Es steckt quasi ein ganzer Ablauf in dieser DLL (angesteuert von meinen Delphiprogramm). Folge: wenn irgendetwas nicht tut, habe ich keine Ahnung wo das Problem liegt. Die DLL ist eine Blackbox und lässt nichts raus. Bei jeder neuen Anlage geht die Fehlersuche von vorne los. Innerhalb der DLL gibt es keine Exceptions mit nützlichen Meldungen sondern nur Fehlercodes. Dummerweise wird immer nur der Fehler 1="es ist ein Fehler aufgetreten" generiert. Auch hier wurde die DLL schon mehrfach weitervererbt. Inzwischen ist kein Programmierer mehr greifbar, der Änderungen an der DLL vornehmen könnte. |
Re: Funktionen in DLL auslagern! Übergabe der Parameter!
So wie ich das verstanden habe, wird im Falle von Rainer "hausintern" entwickelt, der Quellcode der DLLs sollte also erhalten bleiben. :gruebel:
Zitat:
Aber ich finde es interessant zu sehen, wieviele Programmierer nicht in der Lage sind, eine vernünftige Fehlerbehandlung, egal womit, zu implementieren. ("Fehler? In meinen Programm? Muahahahahahaha....") :mrgreen: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:30 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz