![]() |
C++-Lib/Dll in Delphi einbinden
Hi,
Ich möchte mit einem Freund zusammen ein Gemeinschaftsprojekt machen. Das Projekt soll ein FileSharer fürs Lan sein. Ich mache dann das Formblatt mit allem was dazugehört (Ordnerauswahl, Dateiliste, ...) Er macht dann die eigentliche Datenübertragung. Das Problem: Ich nehme Delphi, er C++. Nun gibt es ja die Möglichkeit eine mit C geschriebene Lib/Dll in Delphi einzubinden. Dazu habe ich nun ein paar fragen... 1) Wo genau ist der Unterschied zwischen einer Lib und einer Dll? 2) Wie kann man die jeweils einbinden? 3) Welches sollte man nehmen? 4) Gibt es nicht Typenkonflikte? Wie übergebe ich am einfachsten ein array of String z.B.? ich hoffe ihr könnt mir da ein wenig weiterhelfen... |
Re: C++-Lib/Dll in Delphi einbinden
Hi,
Zitat:
2) Bei libs weiß ich nicht, ob du die einbinden kannst, wird aber sicher irgendwer hier wissen. DLLs kannst du auf zwei Arten einbinden. Die findest du schnell mit der Suche in der DP. Geh gleich nochmal näher drauf ein. 3) Hängt davon ab, ob man libs überhaupt einbinden kann. 4) Alle Typen haben ein Pendant in der anderen Sprache (ok, stark verallgemeinert, sollte aber so ziemlich keinen Typen geben auf den das nicht zutrifft). Wichtig ist, die Typen richtig zu überführen. Ich glaube in C++ wirst du nicht wirklich ein String finden (ist wenn ich mich nicht irre sehr Delphi spezifisch), aber C++ kennt dafür ein PChar (*Char oder so). Wenn du ein Array of PChar hast, entspricht das dann einem (**Char). Es gibt halt für so ziemlich alle primitiven Typen eine Übersetzung und alles andere lässt sich aus primitiven Typen zusammenbauen. Der Aufwand kann nur stark varrieren. Auch zur Umwandlung spezieller Typen gibt es Tabellen und Erklärungen und viel Hilfe in der DP nochmal zu 2), mit der einfachsten Methode: Wenn du eine DLL einbinden möchtest, kannst du die Methoden, die in der DLL exportiert werden in deiner Unit benutzen. Dazu schreibst du deren Namen ganz normal in den Interface Teil, markierst diese jedoch als external und gibst die Datei an, aus der die geladen werden. Wichtig ist dabei, die Groß/Kleinschreibung der Methoden zu beachten (DLLs sind da nicht so flexibel wie Delphi) und die Aufrufkonventionen (z.B. pascal oder stdcall), die legen fest, wie die Parameter übergeben werden, wo abgelegt und wer wieder freigibt und so weiter... Bei Delphi Methoden wird natürlich immer pascal (schau mal in die Hilfe, vielleicht heißt es doch anders) benutzt, die meisten C/C++ DLLs die ich benutzt hatte, waren stdcall oder selten mal cdecl (kann dein Kumpel aber auch festlegen). Ja, ein Beispiel sähe dann so aus
Delphi-Quellcode:
Sorry, nicht gerade gut benannte Parameter und Methoden, aber soll nur veranschaulichen, wie man es machen kann. Rate dir dazu den Namen der dll in einer konstanten zu speichern (weniger ärger wenn sich die dll ändert). Bei Reihenfolge von Aufrufkonvention und external Klausel bin ich mir nicht sicher, musst du vielleicht umdrehen (wenn er meckert).
CONST DLL_NAME = 'meineDll.dll';
procedure Proc1(str : PChar; const mem); stdcall; external DLL_NAME; function Func1(param1 : Integer; param2 : Integer) : Int64; stdcall; external DLL_NAME; function Func2(param1 : Integer; param2 : Integer) : Int64; stdcall; external DLL_NAME; implementation end. Ansonsten war es das schon. Kannst den Methoden auch eigene Namen geben und dann einen Verweis auf die Methode in der Dll machen. Und in diesem Fall hast du natürlich auch nichts vom dynamischen Linken, denn alle Funktionen werden beim Start deines Programms direkt gelinkt (also recht statisch). Es gibt auch einen Weg dies erst beim Aufruf der Methode zu machen (Ressourcen schonender, aber auch langsamer und komplizierter). Wie gesagt, dies ist der einfachste Weg. Gruß Der Unwissende |
Re: C++-Lib/Dll in Delphi einbinden
Zitat:
Zitat:
Zitat:
Zitat:
Zu DLLs kann ich ![]() |
Re: C++-Lib/Dll in Delphi einbinden
Was heisst "libs werden statisch und dll's dynamisch gelinkt"?
was macht das für einen Unterschied? Zu den Parametern: Ich möchte halt auch einen Array of String (Idealerweise sogar eine TStringList^^) übergeben. wie sähe dazu ein beispiel aus? Also die parametertypen in beiden Sprachen... |
Re: C++-Lib/Dll in Delphi einbinden
Also das mit der Stringlist dürfte Schwierig werden. Wenn du den Borland C++ Builder (wie auch immer der bei Borland heißt) benutzt, hast du evtl. eine VCL die dir auch in C++ die TStringList zur Verfügung stellt. Aber für alle anderen C++ Compiler dürfte TStringList nicht wirkich existieren (auch wenn es wohl Alternativen gibt, jedoch dürften die nicht kompatibel sein).
Du hast eigentlich zwei Möglichkeiten, du schreibst die Klasse komplett in C++ nach (eher von abzuraten) oder du verwendest halt wirklich lieber ein Array vom Typ String. Da hast du das Problem, dass Delphi Strings ein ziemlich eigener Weg sind. Du hast (wie tommie-lie schon schrieb) zwar ein String, aber (was ich eigentlich auch meinte) ist, dass du keinen Delphi-kompatiblen String hast. Wenn du ein Array von String übergeben willst, musst du den Umweg über ein Array von Array von Char gehen. Ein Array von Char (char* in C) entspricht natürlich einem PChar. Und ein Array von PChar (char** in C) ist dann das was du brauchst. Wäre jetzt zumindest für C (ohne ++) das was mir als direkte Entsprechung einfällt. Hab aber nie wirklich genug mit C/C++ gemacht um bessere Alternativen ausschließen zu können. Jedenfalls müsstest du bei C (wieder ohne ++) unbedingt die Dimensionen von Arrays angeben. Sonst hast du ganz schnell das Problem, dass du nicht weißt wo das Array endet (gibt in C kein length). Alternativ kannst du auch eine einfache Liste schreiben. Einfach in soweit, dass du die in Delphi und dein Kumpel in C++ schreiben kann. Dann habt ihr die entsprechung und könnt die unter verschiedenen Namen in C++ und Delphi benutzen. Gruß Der Unwissende |
Re: C++-Lib/Dll in Delphi einbinden
Ja, das es die TStringList in C++ so nicht gibt hatte ich schon befürchtet :)
Beispiel: ich will ein array of String nach C++ übergeben. wie sähe das denn konkret als Code aus? |
Re: C++-Lib/Dll in Delphi einbinden
Ok, nochmal, du kannst einfach kein Array of String ohne weiteres übergeben (denke ich), da ein String anders organisiert sein dürfte als ein PChar. Auch wenn du die (dank Compilermagic) ohne Probleme wandeln kannst, benutz lieber Array of Array of Char. Die kannst du so benutzen wie immer (unter Delphi). Und der Rückgabetyp einer deiner Funktionen ist jetzt so ein Array of Array of Char
Delphi-Quellcode:
Dann kannst du in C++ nun diese Funktion (über die DLL) einfach aufrufen und hast etwas wie
function f1 : Array of Array of Char; stdcall;
begin .... end; _stdcall char** f1(); // Bin mir hier (insbesondere mit stdcall) nicht ganz sicher Sorry, weiß nicht genau auf welcher Seite du jetzt genau das Problem hast |
Re: C++-Lib/Dll in Delphi einbinden
Zitat:
also einfach einen konkreten Codeschnipsel der ein array of array of Char von Delphi nach C bringt und umgekehrt. weil: stdcall? ja/nein wie sieht dann der aufruf genau in C aus? ... |
Re: C++-Lib/Dll in Delphi einbinden
Zitat:
Zitat:
Zitat:
Ein char **, was von dir angesprochen wurde, ist ja wieder was anderes. Aber auch hier könnte (und sollte) man das Ende des Strings als NULL kennzeichnen. Zitat:
Was ein array of array of Char angeht, bin ich mir im Augenblick auch unsicher, Delphi muss ja für die "Open Array Parameters" auch irgendwie die Länge nachverfolgen können. Es könnte aber ähnlich wie bei dynamischen Arrays keinen Unterschied machen, wenn man mit dem Pointer arbeitet, da bei dynamischen Arrays die Metainformationen ja vor dem Datenbereich liegen. Ich würde sagen, daß man am sichersten mit der oben von mir dargestellten Aneinanderkettung von Strings arbeitet, oder mit einem PPChar. |
Re: C++-Lib/Dll in Delphi einbinden
Delphi-Quellcode:
sollte nicht
array of char
Code:
enstsprechen, da Delphi bei array of ohne Range zusätzlich noch eine Längenbeschreibung ablegt.
char *
Delphi-Quellcode:
C-Definition:
type
PStrList = ^TStrList; TStrList = array [0..0] of PChar; var pLst : PStrList; lst : TStringList; i : Integer begin GetMem(pLst, lst.Count * SizeOf(Pointer)); try for i := 0 to lst.Count - 1 do pLst[i] := PChar(lst[i]); // weil hiner einem Delphi String eigentlich ein PChar liegt // Call C - Function func(pLst, lst.Count); finally FreeMem(pLst); // kann nicht in der anderen Dll freigegeben werden, da C einen anderen Speichermanager hat end; end;
Code:
__stdcall void func(char **, int);
Delphi-Quellcode:
procedure func(pStrs : PStrList; iLen : Integer); stdcall;
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:42 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