AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Funktionen in DLL auslagern! Übergabe der Parameter!
Thema durchsuchen
Ansicht
Themen-Optionen

Funktionen in DLL auslagern! Übergabe der Parameter!

Ein Thema von R2009 · begonnen am 11. Dez 2009 · letzter Beitrag vom 12. Dez 2009
Antwort Antwort
Seite 1 von 2  1 2      
R2009

Registriert seit: 9. Mär 2009
Ort: Heidelberg
440 Beiträge
 
Delphi 2007 Professional
 
#1

Funktionen in DLL auslagern! Übergabe der Parameter!

  Alt 11. Dez 2009, 06:41
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
Rainer Unger
Mein Profil:
Studium Allgemeine Elektrotechnik TH Darmstadt
Entwicklung von Tools für die Rundsteuer und Zählertechnik.
uP's Atmel Prozessoren (ATmega16,32,88...) in C und Assembler.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: Funktionen in DLL auslagern! Übergabe der Parameter!

  Alt 11. Dez 2009, 07:06
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.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#3

Re: Funktionen in DLL auslagern! Übergabe der Parameter!

  Alt 11. Dez 2009, 07:06
Zitat von R2009:
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.
Ja. Bei C++ mit C-Kompatibler Schnittstelle und für C++/C+ über (bei .NET muß hier nur das Assembly COM-Visible gemacht werden)

Zitat von R2009:
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.
Beide oben genannten Möglichkeiten stehen offen wobei die COM-Version elegander ist aber die C-Kompatible Schnittstelle ohne Installation auskommt (ok, wenn man ab W2k/XP aufsetzt kann man bei COM SideBySide registrierung verwenden

Zitat von R2009:
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?
Bei COM kein Problem, bei C-Kompatibler Schnittstelle muß mann sich passende Funktionen ausdenken.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#4

Re: Funktionen in DLL auslagern! Übergabe der Parameter!

  Alt 11. Dez 2009, 07:08
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
42
  Mit Zitat antworten Zitat
Astat

Registriert seit: 2. Dez 2009
Ort: München
320 Beiträge
 
Lazarus
 
#5

Re: Funktionen in DLL auslagern! Übergabe der Parameter!

  Alt 11. Dez 2009, 23:34
Hallo R2009.

Also bei Verwendung von Win32 und Delphi, C, C++ würde ich folgende API verwenden.

Delphi-Quellcode:

TCallBackProcedure = function(ptrData: Pointer; cbData: LongInt): LongBool; stdcall;

function Generic(cbProc: Pointer; ptrData: Pointer; cbData: LongInt): LongBool; stdcall;
Damit ist mit einer einzigen Funktion, die Übergabe aller möglichen Win32 Datentypen, Structuren etc. möglich.

Hier ein Beispiel wie, über eine Struct, array of integer, über die API ausgetauscht werden kann.

Delphi-Quellcode:
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;
Es müssen vorher nur in einem Pflichtenheft, die ID's für bestimmte Datenstrukturen festgelegt werden.
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
Lanthan Astat
06810110811210410503210511511603209711003210010110 9032084097103
03211611111604403209711003210010110903210010510103 2108101116122
11610103209010110510810103206711110010103210511003 2068101108112
10410503210310111509910411410510109810111003211910 5114100046
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.149 Beiträge
 
Delphi 12 Athens
 
#6

Re: Funktionen in DLL auslagern! Übergabe der Parameter!

  Alt 12. Dez 2009, 00:00
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Astat

Registriert seit: 2. Dez 2009
Ort: München
320 Beiträge
 
Lazarus
 
#7

Re: Funktionen in DLL auslagern! Übergabe der Parameter!

  Alt 12. Dez 2009, 01:26
  • himitsu hat folgendes geschrieben.

Zitat:
DLLs in C# müßten doch auch gehn?
Ja natürlich, aber wenn ich schon Native Win32-API Coder zur Verfügung habe, würde ich auch alles konsequent,
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
Lanthan Astat
06810110811210410503210511511603209711003210010110 9032084097103
03211611111604403209711003210010110903210010510103 2108101116122
11610103209010110510810103206711110010103210511003 2068101108112
10410503210310111509910411410510109810111003211910 5114100046
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#8

Re: Funktionen in DLL auslagern! Übergabe der Parameter!

  Alt 12. Dez 2009, 07:29
Zitat von Astat:
Zitat:
DLLs in C# müßten doch auch gehn?
Ja natürlich,
Echt? Nur weil die Endung einer Assembly 'DLL' ist, heißt das ja noch lange nicht, das ich die von Delphi aus einfach so nutzen kann.

Zitat von Astat:
...sind Böse...Sockets sind Böse...
In der modernen Softwareentwicklung ist alles 'böse', was das Rad neu erfinden will. Das kostet nämlich Zeit, ist mindestens am Anfang fehleranfällig und wirft einen zurück. Daher ist alles 'gut', was standardisiert und erprobt ist. Das ist dann vielleicht nicht so performant, aber es läuft und ich habe eine Baustelle weniger. Datenaustauschformate sind lästig und brauchen Zeit, bis sie perfekt sind: XML ist fix und fertig: Ich kann die Daten in eine einfache Textdatei schreiben, automatisch prüfen, transformieren usw usw usw. Was soll daran böse sein? JSON geht auch, ist sogar etwas kompakter (und mir lieber), aber da muss ich auch bei der Gegenstelle nachfragen, ob die das können.

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.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#9

Re: Funktionen in DLL auslagern! Übergabe der Parameter!

  Alt 12. Dez 2009, 12:26
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.
fork me on Github
  Mit Zitat antworten Zitat
Benutzerbild von Mithrandir
Mithrandir
(CodeLib-Manager)

Registriert seit: 27. Nov 2008
Ort: Delmenhorst
2.379 Beiträge
 
#10

Re: Funktionen in DLL auslagern! Übergabe der Parameter!

  Alt 12. Dez 2009, 12:39
So wie ich das verstanden habe, wird im Falle von Rainer "hausintern" entwickelt, der Quellcode der DLLs sollte also erhalten bleiben.

Zitat:
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.
Eigentlich mag ich Fehlercodes, denn die kann man auch in C nutzen. Formuliert man die Konstanten dazu passend, kann damit jeder was anfangen. Wenn aber jeder Fehler denselben Code zurückwirft... Nun ja, dann wäre ihm wahrscheinlich auch mit Exceptions nicht geholfen gewesen...

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....")
米斯蘭迪爾
"In einer Zeit universellen Betruges wird das Aussprechen der Wahrheit zu einem revolutionären Akt." -- 1984, George Orwell
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz