Autor Beitrag
cscheffl
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Fr 25.02.05 21:35 
Hallöchen

Zuerst mal: Sorry, hab nicht so recht gewusst wohin mit dieser Frage.
Wer einen Tip hat wo Delphi <-> C++ hingehört kanns mal mit nennen, danke.

Meine Frage ist:
Wie kann ich eine unter Delphi(5) kreierte Dll in C++ (genauer im Borland Builder5) einbinden/nutzen.
Allgemein, das Einbinden hab ich schon hinbekommen, nur eben noch nicht mit Pascal-compilierten Dlls.
Aber habe mir sagen lassen das soll gehen.
Vermute es liegt an den Aufrufkonventionen.
In Literatur findet man so schöne Beisiele wie:
c++ -> Delphi
Delphi -> VB
...
Aber wo ist Delphi -> C++ :?



Untenstehend eine Listung "was ich schon habe":

- Die delphidll.dll:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
library delphidll; 

uses 
  SysUtils, 
  Classes; 

{$R *.RES} 

function Anzeigen: integer; stdcall; 
begin 
result:=10; 
end; 

exports 
  Anzeigen; 

begin 
end.




- die daraus erzeugte lib Datei delphidll.lib (hab ich mit dem Borland-Tool implib erzeugt).

- die Programmunit(bzw. deren header-Datei) die die dll nutzt
enthält die Importdeklaration:


ausblenden Quelltext
1:
int __declspec(dllimport) Anzeigen(void);					






- das Programm an sich in dem Anzeigen() aufgerufen wird:
(diese Funktion bitte mehr als Beispiele sehen , klar nicht.. :wink: )
Darin er folgt in untenstehender Form der Aufruf .


ausblenden Quelltext
1:
2:
Form1->Caption = IntToStr(Anzeigen());   
// hier erfolgt aufrufen der dll-Funktion





Also wäre echt ne Hilfe wenn da jemand einen Rat hätte.
Wenn da schon die (reine) C++ Community nicht so ne echte Hilfe ist...
Nehme alles: Links, kleine Hinweise,...

Bis jetzt wiedersetzt sich das Programm jedenfalls noch standhaft jedem Comp.versuch
mit nem Linker Fehler:
Unresolved external Anzeigen() referenced from ... Unit1.obj

Also es wird wohl ein Fehler sein... ??

Danke, Danke schonmal
C

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.
Net-Spider
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Fr 25.02.05 21:44 
das riecht mir stark danach, als müsstest du in c++ die lib noch einbinden, so dass der linker diese auch findet,
die fehlermeldung mit unresolved external kenn ich zur genüge, das war jeweils die lösung dazu.
irgendwo in den projekteinstellungen kannst du sicherlich den namen der lib eintragen (+ pfad?)
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Sa 26.02.05 12:48 
Also so wie du die Funktion importierts schaut mir das auch sehr nach einem Problem mit der Aufruf-Konvention aus.. Änder mal die Aufruf-Konvention in deiner DLL von stdcall auf cdecl...

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Net-Spider
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Sa 26.02.05 13:57 
ist die aufrufkonvention nicht nur interessant wenn man parameter übergibt?
das war doch hier nicht der fall, oder irre ich mich?
cscheffl Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: So 27.02.05 12:36 
Ja danke erstmal für das Interesse :D

Habs es gleich mal probiert mit dem cdecl Aufruf - geht noch nicht.
Sieht jetzt so aus.
Warum muss ich eigentlich die Funktion nicht noch im exports - Teil der dll genau so deklarieren(mit Aufrufkonvention)?

ausblenden Delphi-Quelltext
1:
function Fensterzeigen: integer; cdecl;					


(Übrigends: wie kann man statt "code" was anderes schreiben, einfach ersetzen, habs versucht, klappt net)
Moderiert von user profile iconMotzi: Habs für dich ersetzt - einfach "delphi" statt "code".. ;)

Hab mich auch nochmal vergewissert ob die lib eingebunden ist.
Sie ist es(hab ich über Project hinzufügen gemacht).
Es könnte natürlich daran liegen das ich die mit dem Borland-Tool erzeugt habe - oder??
Da ich mir deswegen unsicher war hab ich es mal es mit einer in C++ geschriebenen Dll versucht,
d.h. mal diese dll hergenommen und aus dieser die dazugehörige lib mit dem implib erzeugt.
Die funktioniert.

Was besonders verwunderlich ist, das die dynamische Einbindung der Delphi-Dll auch läuft.
Dort hab ich es hinbekommen auf die interne Funktion zuzugreifen.
Da braucht man ja z.B. keine lib-Datei(welch übles Teil..., warum kommt C++ nicht ohne diese aus, wie Delphi)
Aber das muss doch auch statisch gehen?

Zu den Aufrufkonventionen mit stdcall hab ich jedenfalls gefunden das man das immer machen sollte, auch bei Fkt. ohne Parametern, da in C++ ja zumindest void davorsteht(ist ja quasi auch wie ein "Typ").
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: So 27.02.05 12:40 
ich hab mir gestern auch mal eine lib aus einer dll erstellen lassen
das problem hierbe ist das der name des exports sich ändert

myisNT
war dann auf einaml
_myisNT@@0

oder so :> öffne die lib mal dann siehste wie der aussieht
UC-Chewie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 531

WinXP
D5 Ent
BeitragVerfasst: So 27.02.05 13:33 
Ich bin jetzt nicht so der C-Guru, aber wieso willst du eine .lib-Datei anlegen? lib-Dateien sind soweit ich weiß doch nur statische Bibliotheken, die vom Linker ins Binary mit eingelinkt werden. Was spricht gegen die dynamische Einbindung?

Und wegen der Änderung des Namens: Falls du einen Anhaltspunkt brauchst zum Suchen, das ganze nennt sich Suche bei Google NAME MANGLING

_________________
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
cscheffl Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: So 27.02.05 22:58 
Ja mit dem Funktionsname ändern, das könnte schon stimmen.
Da hab ich auch schon mal was dahingehendes "gehört".
Z.B. das mit dem Unterstrich davor.

Anbei mal der Code der Lib-Datei(mit dem Win üblichen Text-Editor geöffnet)
Ich kann da natürlich nun nicht so viel drausnehmen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
ð
            € 
Anzeigen ˆ#   
Anzeigen
delphidll.dll #ˆ  û  tŠ  t          ñ�                                                                                                                                                                                                                                                                                                                                                                                                                            q                                    
Anzeigen


Nur wie sollte ich die Deklaration dann vornehmen(in der Headerdatei der die Dll nutzenden Programmes)
So z.B. falls wir mal annehmen es würde sich nur um den Unterstrich handeln??
ausblenden Delphi-Quelltext
1:
int __declspec(dllimport) _Anzeigen(void);					



Und wegen der dynamischen Einbindung, ist schon klar, das ist die bessere Variante.
Aber warum geht die statische nicht??
Ihr habt schon recht, ich würde mich jetzt mal daran nicht festbeißen.
Wenn jemand aber noch ne Idee hat, was es sein könnte, wäre es gut.
Kurz: Ich geb's mal noch nicht als "gelöst" aus.
Aldarin
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mi 16.03.05 19:33 
Hallo,

zu dem ganzen leidigen Thema habe ich noch ein paar Fragen was VC++ betrifft:

Ich versuche eine Delphi DLL in VC++ einzubinden. Den Artikel burks.brighton.ac.uk...f/pages/delphenc.htm habe ich bereits gelesen.

Dieser Artikel bezieht sich auf D2 geht das unter D5 genauso?
Kann man eigentlich auf die LIB Datei nicht verzichten? IMHO werden unter VC++ die Funktionen vom Kernel32 doch auch ohne LIB-Datei importiert?
Hat evt. jemand Erfahrung was das betrifft und kann mir einen Tip geben wie man eine D5 DLL in VC++ korrekt (statisch) importiert? Gibt es da auch noch andere Möglichkeiten?

Gruß
Aldarin
cscheffl Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Mi 16.03.05 20:09 
@Aldarin:

Ich geb dir nur den Rat, mach die Einbindung doch dynamisch.
Hab mich lange mit der statischen Var. herumgeplagt, dynamisch gehts super, einfacher(wer hätte das gedacht) und es scheint keinerlei Nachteile zu haben!!
Du kreierst einfach noch ne Unit, die sozusagen als Interface-Unit zur Dll dient.
Darin kannst du dann gleich noch die "Inhaltserklärung" für die Dll machen(falls man sie weitergeben will, braucht man das ja sowieso). Die sieht dann z.B. für obige Fensterfunktion so aus, oder besser gesagt die Interface-Funktion:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
void Fensterzeigen()
{
TFunktionszeiger* Fensterzeigen; //Variable des Zeigertyps(dieser Typ ist in der DLLImp.h definiert).
int Erg;
HINSTANCE DllInstanz = LoadLibrary("dlltest32.dll"); //DLL wird bei Bedarf geladen.

    if (DllInstanz != 0) Fensterzeigen = (TFunktionszeiger*)GetProcAddress(DllInstanz, "Fensterzeigen");
    if (Fensterzeigen != NULL) Fensterzeigen(); //Aufruf der DLL-Funktion.
    else ShowMessage("Dll 'dlltest32.dll' konte nicht gefunden werden! Bitte in das Programmverzeichnis kopieren.");
FreeLibrary(DllInstanz); //..und nach Gebrauch entladen.
}


Wenn du was erklärt haben möchtest, postest du halt nochmal hier, gibts dann.

Im übrigen bin ich auch noch an der statischen Lösung interessiert, also falls du es hinbekommen haben solltest.
Schreib nochmal!
-->C
Aldarin
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mi 16.03.05 20:26 
Hi,
Eigentlich tendiere ich zur Statischen.
wo hast Du denn die großen Probleme bei der statischen Variante bis jetzt gehabt? Nur damit ich die Fehler die Du bis jetzt gemacht hast vermeiden kann.

Ich halte meine Funktionen, was die Typen betrifft, sehr eng an die Konventionen wie Sie von Windowx API-Funktionen vorgegeben werden.

So habe ich eine Funktion:
ausblenden Quelltext
1:
2:
3:
4:
function MyFindFirstFileExA(lpFileName: LPCTSTR; 
  fInfoLevelId: TFindexInfoLevels; lpFindFileData: Pointer; 
  fSearchOp: TFindexSearchOps; lpSearchFilter: Pointer; 
  dwAdditionalFlags: DWORD): THandle; stdcall;

in D% definiert und müßte doch eigentlich diese Funktion statisch in VC++ folgendermaßen importieren können:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
#define WINAPI      __stdcall
#define WINBASEAPI DECLSPEC_IMPORT

WINBASEAPI
HANDLE
WINAPI
MyFindFirstFileExA(
    LPCSTR lpFileName,
    FINDEX_INFO_LEVELS fInfoLevelId,
    LPVOID lpFindFileData,
    FINDEX_SEARCH_OPS fSearchOp,
    LPVOID lpSearchFilter,
    DWORD dwAdditionalFlags
    );

oder sehe ich das komplett falsch?

Gruß
Aldarin