![]() |
Mit DLLs arbeiten
Hallo,
ich habe eine Funktion programmiert, die mir einen bestimmten String zusammen baut. Diese Funktion möchte ich in eine DLL auslagern. Ich habe irgendwie gehört, dass es nicht funktionieren soll. Ich habe auch schon vor einiger zeit mal was probiert und das hat auch nicht funktioniert. Ist es überhaupt möglich mit Dlls String übergeben zu lassen? so baue ich meine DLLs immer aus:
Delphi-Quellcode:
Importiert wird im Programm mit folgender Definition:
library Project1;
{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muß die erste Unit im Uses-Anweisungsteil des Interface-Abschnitts Ihrer Unit sein, wenn Ihre DLL Prozeduren oder Funktionen exportiert, die String-Parameter oder Funktionsergebnisse übergeben. Dies gilt für alle Strings die an und von Ihrer DLL übergeben werden -- selbst für diese, die in Records oder Klassen verschachtelt sind. ShareMem ist die Schnittstellen-Unit zur DELPHIMM.DLL, welche Sie mit Ihrer DLL weitergeben müssen. Um die Verwendung von DELPHIMM.DLL zu vermeiden, übergeben Sie String-Parameter unter Verwendung von PChar- oder ShortString-Parametern. } uses SysUtils, Classes; function Rechne(a, b : Integer) : Integer; begin Result:=a + b; end; exports Rechne name 'Rechne'; begin end.
Delphi-Quellcode:
Rechne(a, b : Integer) : Integer; external 'Project1' name 'Rechne';
|
Re: Mit DLLs arbeiten
du hast die Lösung doch bereits selbst gepostet :wink: Lese dir mal den Text zwischen "library Project1;" und "uses" durch!!
[Edit]Es ist schicker hinter Externale den vollständigen Dateinamen zu schreiben ('Project1.dll' anstelle von 'Project1'). Und die explize Angabe von Name kannst du auch weglassen wenn die Funktion genau so heißt wie in der DLL.
Delphi-Quellcode:
oder
Rechne(a, b : Integer) : Integer; external 'Project1.dll';
Delphi-Quellcode:
Irgendwas(a, b : Integer) : Integer; external 'Project1.dll' name 'Rechne';
|
Re: Mit DLLs arbeiten
Der Kommentar ist anscheinend nicht auffällig genug :D
|
Re: Mit DLLs arbeiten
Hallo,
ich glaube ich stehe gerade ein bisschen auf dem schlauch. Irgendwie verstehe ich den komentar nicht. kann mir das jemand nochmal verständlich erklären? Ich würde mich freuen. MFg Christian18 |
Re: Mit DLLs arbeiten
Delphi-Quellcode:
Der ist gemeint.
{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muß die
erste Unit im Uses-Anweisungsteil des Interface-Abschnitts Ihrer Unit sein, wenn Ihre DLL Prozeduren oder Funktionen exportiert, die String-Parameter oder Funktionsergebnisse übergeben. Dies gilt für alle Strings die an und von Ihrer DLL übergeben werden -- selbst für diese, die in Records oder Klassen verschachtelt sind. ShareMem ist die Schnittstellen-Unit zur DELPHIMM.DLL, welche Sie mit Ihrer DLL weitergeben müssen. Um die Verwendung von DELPHIMM.DLL zu vermeiden, übergeben Sie String-Parameter unter Verwendung von PChar- oder ShortString-Parametern. } |
Re: Mit DLLs arbeiten
den kommentar meine ich jairgendwie verstehe ich den nicht.
|
Re: Mit DLLs arbeiten
Wenn Du Strings an die DLL übergeben willst oder die DLL selbst Strings zurückgeben soll, musst Du ShareMem einbinden, und zwar als erste Unit (sowohl in der DLL als auch in der Anwendung). Der einfachere Weg ist allerdings, keine Strings zu übergeben, sondern PChars.
[edit] Nachtrag: wenn Du nicht auf Strings verzichten willst und den Weg über ShareMem gehst, musst Du zusätzlich zur Anwendung und der DLL noch die DELPHIMM.DLL an den Endkunden weitergeben, sonst nützt Dir ShareMem nichts. [/edit] |
Re: Mit DLLs arbeiten
Zitat:
|
Re: Mit DLLs arbeiten
Auf die Erwähnung alternativer Speichermanager hatte ich bewusst verzichtet, um die Verwirrung nicht noch größer zu machen ;)
|
Re: Mit DLLs arbeiten
Ich verzichte auf Strings denn Pchar's sind nichts anderes und umwandeln ist einfach und die Speicherauslastung in der DLL und der anwendung ist auch gleiner.
Sollte man auf diese ShareMem dll nicht verzichten wird das Projekt unnötig in die Grösse gezogen. Gruss Sascha |
Re: Mit DLLs arbeiten
Ich bin auch bereits vor Jahren dazu übergegangen, im Zusammenhang mit DLLs PChars zu verwenden. Ist ja nicht mehr so ein Akt mit dem Typecasting wie noch zu Win16-Zeiten.
|
Re: Mit DLLs arbeiten
Wenn man viel mit WinApi-Funktionen gearbeitet hat ist man die Arbeit mit PChars gewohnt so das man auch nicht casten muss sondern einfach nur mit Speicheradressen rum hantiert. Wenn man sich dran gewöhnt hat genießt man voller Freunden die Geschwindigkeitsvorteile.
[Edit]Editiert weil es den Text nicht angezeigt hat *grübel*grummel*[/Edit] |
Re: Mit DLLs arbeiten
@Jens: wie bitte?
|
Re: Mit DLLs arbeiten
Zitat:
Delphi-Quellcode:
Die Zeiten von StrPas, StrCopy und Konsorten sind ja Gott sei Dank vorbei.
Bla := Funktion_aus_DLL(PChar(String_aus_Anwendung));
|
Re: Mit DLLs arbeiten
Zitat:
|
Re: Mit DLLs arbeiten
Hallo,
ihr redet die ganze zeit von Pchar und so, hat jemand vieleicht mal ein kleines beispiel, wie sowas aussieht? MFG Christian18 |
Re: Mit DLLs arbeiten
Delphi-Quellcode:
implementation
type TSummenFunktion = function(zahl1, zahl2: integer): integer; stdcall; function addieren(zahl1, zahl2: integer): integer; var SummenFunktion: TSummenFunktion; Handle: THandle; begin Handle := LoadLibrary(PChar(ExtractFilePath(ParamStr(0))+'rechenpro.dll')); if Handle <> 0 then begin @SummenFunktion := GetProcAddress(Handle, 'addiere'); if @SummenFunktion <> nil then begin result:=SummenFunktion(zahl1, zahl2); end; FreeLibrary(Handle); ![]() |
Re: Mit DLLs arbeiten
Zitat:
Außerdem mein üblicher Hinweis bei dem Thema: WideString lässt sich ohne Tricksereien zwischen Echse und DLL (und auch anderen Sprachen, weil normaler OleString aka BSTR) PChar zu verwenden, ohne eine Kopie des Strings zu übergeben ist ein wenig heikel. Da Stringinstanzen in Delphi auf mehrere Referenzen verteilt sein könnten, könnten so aus Versehen auch andere Variablen/Felder mit dem ehemals gleichen Wert mitgeändert werden. Nicht zu vergessen, dass das schnell sehr, sehr hässlicher Code wird... :? |
Re: Mit DLLs arbeiten
Zitat:
Delphi-Quellcode:
DLLUnit:
library TestDLL;
{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss sich in der ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt- Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL. Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String- Informationen als PChar- oder ShortString-Parameter übergeben. } uses DLLUnit in 'DLLUnit.pas'; exports Meldung; begin end.
Delphi-Quellcode:
Und die Hauptunit des aufrufenden Programms:
unit DLLUnit;
interface uses Windows; function Meldung(sMeldung: PChar): DWORD;stdcall; implementation function Meldung(sMeldung: PChar): DWORD;stdcall; begin Result := MessageBox(0,sMeldung,nil,0); end; end.
Delphi-Quellcode:
unit AppUnit;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} function Meldung(sMeldung: PChar): DWORD;stdcall;external 'TestDLL.dll'; procedure TForm1.FormCreate(Sender: TObject); begin Meldung('Huhu'); end; end. |
Re: Mit DLLs arbeiten
Hallo,
ich habe auch noch einmal eine Frage zu Strings und DLLs. Kann ich innerhalb der DLL mit Strings arbeiten ohne das ich einen Speichermanager verwenden zu müssen? Also zumindest wenn ich bei den exportierten Funktionen und Proceduren keinen String übergebe, sondern einen PChar. Danke schon einmal für die Antwort. |
Re: Mit DLLs arbeiten
Zitat:
Zitat:
Zitat:
Zitat:
@DeddyH: das war ein trivial Beispiel. Interesannt wird es aber erst, wenn die DLL Zeichenketten zurückgeben soll. Wie das geht, siehe hier: ![]() @Henry: Innerhalb der DLL kannst du machen, was du willst. Du musst eben nur dann aufpassen, wenn du die Grenzen der Speichermanager (Programm, DLL) überschreiten willst. Zum Verständnis wie das mit den Speichermanager funktioniert, siehe hier: ![]() |
Re: Mit DLLs arbeiten
Zitat:
|
Re: Mit DLLs arbeiten
Zitat:
Mal schauen ob es klappt. Danke erst einmal für die Hilfe. |
Re: Mit DLLs arbeiten
Zitat:
WideString ist etwas langsamer als AnsiString, da es kein nativer Delphi typ ist (keine Referenzzählung, und auch noch Unicode...). Sollte aber nicht viel ausmachen. PChars sind nicht nur heikel, weil man vergessen könnte den String vorher explizit zu kopieren, sie machen deine Anwendung auch viel anfälliger für Buffer overflows. Egal ob unbeabsichtigt, oder als Sicherheitslücke, die andere gezielt ausnutzen könnten... Und wie gesagt, der Code, der mit PCHars arbeitet ist einfach nur hässlich. PChars innerhalb von optimierten Funktionen zu nehmen um Kopiererei zu sparen ist eine Sache (und das macht auch Sinn!), aber sich sinnlos auf diese mittelalterliche Art unnötige Bufferflows oder Umwege anzutun kann ich nicht ganz nachvollziehen... Wenn du weißt, dass die DLL von dir kommt, dann wären auch AnsiString und FastMM ein schöne Lösung. |
Re: Mit DLLs arbeiten
Hallo Robert,
in meinem Fall wäre ich mir sicher das Die DLL von mier kommt ;-) Ich hätte auch prinzipiell kein Problem damit die BORLNDMM.DLL mit meinem Programm auszuliefern. Ich konnte bisher allerdings noch nirgendwo finden wo diese Datei hin muss, damit es funktioniert. Reicht es wenn sie im Programmverzeichnis liegt? So lange es dort liegen kann wäre das auch eine Option für mich. Ich installiere nämlich ungern Dateien in das Systemverzeichnis von jemand anderem. Ein Weiteres Problem ist, wo ausser in der DLL muss ich noch die Unit ShareMem (als erstes) einbinden? Reicht es in der Unit im Programm wo ich die Funktionen importiere, oder auch in allen Units wo ich dann die importierten Funktionen aufrufe? |
Re: Mit DLLs arbeiten
Zitat:
Oder explizit AnsiString, falls du Angst vor binären Inkompatibilitäten mit der nächsten Delphiversion hast. Da dort "String" auf einen UTF16-basierten String zeigen wird. Zitat:
Ziehe dir FastMM und packe den als erste Unit in die Uses clause von allen .DPRs. WideString ist aber trotzdem nicht aus dem Rennen und würde von dir gar nix spezielles erfordern... |
Re: Mit DLLs arbeiten
Hallo,
mein Problem ist hauptsächlich, dass ich nicht nur Strings einzeln übergeben möchte. Ich hatte schon einmal im DelphiForum einen Beitrag zu meinem eigentlichen Problem gestartet und bin immer noch am tüfteln, da es nicht klappt. Ich möchte nämlich komponenten an die DLL übvergeben (z.B. StringGrid) Siehe: ![]() Und dann habe ich hier das Thema gefunden und dachte, frege ich hier mal nach dem Umgang mit dem Speichermanager. Es kann natürlich auch sein das ich da noch ein ganz anderes Problem habe. Kannst es Dir ja mal anschauen, vieleicht hast Du ja eine Idee für mich. Nach FastMM werde ich mal schauen, oder hast du ne Quelle parat? Danke |
Re: Mit DLLs arbeiten
Zitat:
Damit das geht müssen alle Packages, die für die Komponenten benötigt werden als Laufzeit-Packages von DLL und Echse referenziert werden. Das heißt, du musst mindestens die RTL, VCL mitliefern und als Laufzeit Packages angeben. (Unter "Packages" in den Projektoptionen) Das ist die einzige Möglichkeit, damit TStringGrid in der DLL das gleiche wie TStringGrid in der Echse ist. Eine andere Möglichkeit wäre es, wenn du dein StringGrid in ein Interface mit den Methoden verpackst, die du benötigst. Dann bräuchtest du in der DLL nur das Interface benutzen, ohne den Rattenschwanz an Packages mit schleppen zu müssen. (Du kannst hier nach ![]() Packages sind eigentlich ein sehr furchtbares Format für eine Bibliothek, da sie immer nur mit einer ganz speziellen Version des Compilers laufen. Du kannst mit Packages nicht die DLL mit Delphi 7 und die Echse mit 7.1 kompilieren. |
Re: Mit DLLs arbeiten
Ohje, da habe ich mir ja was einfallen lassen.
Ich werde deinem Suchtip mal folgen und schauen ob ich das dann hinbekomme. Hört sich für mich erst mal kompliziert an. Aber mit diesen Packages werde ich dann mal die Finger von lassen, ohne wäre mir auch lieber. Danke Dir erst einmla für die Hilfe. Wenn ich noch fragen dazu habe werde ich mich entweder in einem neuen Beitrag oder per PM melden, denn ich denke das passt dann nicht mehr hier zum Thema ;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:28 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