AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

C++-Lib/Dll in Delphi einbinden

Ein Thema von glkgereon · begonnen am 12. Nov 2005 · letzter Beitrag vom 14. Nov 2005
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#1

C++-Lib/Dll in Delphi einbinden

  Alt 12. Nov 2005, 12:09
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...
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: C++-Lib/Dll in Delphi einbinden

  Alt 12. Nov 2005, 13:41
Hi,

Zitat von glkgereon:
Hi,
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.?
1) Der Unterschied liegt darin, dass eine Lib statisch gelinkt wird, eine DLL dynamisch.

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:
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.
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).
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
  Mit Zitat antworten Zitat
tommie-lie
(Gast)

n/a Beiträge
 
#3

Re: C++-Lib/Dll in Delphi einbinden

  Alt 12. Nov 2005, 14:18
Zitat von Der_Unwissende:
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).
Naja, ein wenig zu verallgemeinert. Auf die Strings bist du ja schon selbst gestoßen, dynamische Arrays gehören auch dazu. Im Prinzip alles, was mit Delphis Compiler-Magic zu tun hat, ist nicht sehr angenehm in C(++) zu verwenden. Prinzipiell existieren aber alle Typen von C (nicht C++) auf irgendeine Art und Weise auch in anderen Sprachen. Darüber hinaus sind Klassen aufgrund unterschiedlichem ABI meist nicht über mehrere Compiler hinweg zu benutzen. Und wo wir schon bei der ABI sind: man sollte sich für die Kommunikation auf eine Aufrufkonvention einigen

Zitat von Der_Unwissende:
aber C++ kennt dafür ein PChar
Aua! std::string Da das aber 'ne Klasse ist, gips die in dieser Form nicht in Delphi.
Zitat von Der_Unwissende:
(*Char oder so).
Fast, "char *"

Zitat von Der_Unwissende:
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).
Nicht zwangsläufig. Ich kann auch bei Delphi festlegen, welche Aufrufkonvention meine Funktion haben soll, und die "normale" Aufrufkonvention in C und C++ ist cdecl. stdcall sind alle Funktionen der Windows-API, weil stdcall prinzipiell die portabelste Aufrufkonvention ist (architektur- und sprachunabhängig). Und weil man das praktishc fand, exportieren viele DLLs von Drittherstellern ihre Funktionen auch als stdcall.


Zu DLLs kann ich Ollis Tutorial wärmstens empfehlen, ich kenne keinen besseren Text über das Thema.
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#4

Re: C++-Lib/Dll in Delphi einbinden

  Alt 12. Nov 2005, 19:32
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...
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#5

Re: C++-Lib/Dll in Delphi einbinden

  Alt 13. Nov 2005, 19:02
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
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#6

Re: C++-Lib/Dll in Delphi einbinden

  Alt 13. Nov 2005, 19:06
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?
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#7

Re: C++-Lib/Dll in Delphi einbinden

  Alt 13. Nov 2005, 19:12
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:
function f1 : Array of Array of Char; stdcall;
begin
....
end;
Dann kannst du in C++ nun diese Funktion (über die DLL) einfach aufrufen und hast etwas wie
_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
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#8

Re: C++-Lib/Dll in Delphi einbinden

  Alt 13. Nov 2005, 19:24
Zitat von Der_Unwissende:
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:
function f1 : Array of Array of Char; stdcall;
begin
....
end;
Dann kannst du in C++ nun diese Funktion (über die DLL) einfach aufrufen und hast etwas wie
_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
Da ich nicht besonder gut C(++) kann hätte ich einfach mal gerne ein Beispiel welches funktioniert
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?
...
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
tommie-lie
(Gast)

n/a Beiträge
 
#9

Re: C++-Lib/Dll in Delphi einbinden

  Alt 13. Nov 2005, 19:36
Zitat von Der_Unwissende:
Du hast eigentlich zwei Möglichkeiten, du schreibst die Klasse komplett in C++ nach (eher von abzuraten)
Dürfte auch unmöglich sein, wie gesagt, das ABI wird sich unterscheiden. Vielleicht nicht zwischen den beiden Borland-Compilern, aber mit Sicherheit zwischen einem anderen C++-Compiler.

Zitat von Der_Unwissende:
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.
Es gibt auch für C++ keine Alternativen, außer Interfaces mit 'nem entsprechenden Objektsystem dazwischen (COM. CORBA, Weißdergeier).

Zitat von Der_Unwissende:
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).
Kommt drauf an. In C stehen dir String-Funktionen zur Verfügung, mit denen arbeitet es sich sehr schön, wenn die Strings alle nullterminiert sind. Listen von Strings werden oft als nullterminierte Liste von Strings übergeben, also jede Menge nullterminierte Strings, dann ist das letzte Zeichen ein NULL-Character, und wo als nächstes ein String kommen würde, einfach noch ein NULL-Character. Das letzte Element ist also ein Nullstring und markiert das Ende der Liste. Das Ganze funktioniert dann so, daß nur ein Pointer auf den allerersten String übergeben wird. Zu dessen Ende gelangt man mit Pointerarithmetik und der strlen()-Funktion, ein Zeichen weiter befindet sich das erste Zeichen des zweiten Strings. Das kann man wunderschön in einer Schleife in ein std::vector<std::string> einlesen, bis man als nächstes Zeichen nicht mehr den ersten Buchstaben des nächsten Strings erhält, sondern den NULL-Character.
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 von Der_Unwissende:
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.
Ein array of String dürfte einem char ** entsprechen, vermute ich. Solange man die Daten nicht verändert, müsste es klappen, aber ganz sicher bin ich mir nicht.
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.
  Mit Zitat antworten Zitat
neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#10

Re: C++-Lib/Dll in Delphi einbinden

  Alt 14. Nov 2005, 01:11
array of char sollte nicht
Code:
char *
enstsprechen, da Delphi bei array of ohne Range zusätzlich noch eine Längenbeschreibung ablegt.

Delphi-Quellcode:
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;
C-Definition:
Code:
__stdcall void func(char **, int);
procedure func(pStrs : PStrList; iLen : Integer); stdcall;
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  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 05: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