Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Funktion aus der Dll aufrufen? (https://www.delphipraxis.net/29754-funktion-aus-der-dll-aufrufen.html)

egal 14. Sep 2004 11:43


Funktion aus der Dll aufrufen?
 
Das Problem liegt darin, dass dll in Fortran mit Hilfe von Fortran-Compiler geschrieben wurde. Delphi findet schon Funtion in dieser Dll, ich kann die sogar aufrufen, aber ich bekomme total falschen Wert. Hier ist ein Teil von meiner Quellcode:

Delphi-Quellcode:
function VPUNK(t2:integer) : integer; external 'quelle.dll'; // rufe diese funktion VPUNK auf.

implementation

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject);
var cPfad, c1 : string;
     a,t2: integer;
begin
  t2 := 3;
  a := VPUNK(t2); // verwende sie
  c1:= inttostr(a);
Statt 6 bekomme ich so ein Ergebnis: -2334563. Und ich weiß jetzt nicht genau, wo liegt der Fehler: entweder in Dll oder ich mache in meiner Code was falsch? Danke. 8)

sakura 14. Sep 2004 11:44

Re: Funktion aus der Dll ausrufen?
 
Hi egal,

verwende doch bitte die [delphi]-Tags ;-)

...:cat:...

egal 14. Sep 2004 11:46

Re: Funktion aus der Dll ausrufen?
 
Zitat:

Zitat von sakura
Hi egal,

verwende doch bitte die [delphi]-Tags ;-)

...:cat:...

ok, habe geändert

Luckie 14. Sep 2004 11:56

Re: Funktion aus der Dll aufrufen?
 
Schreib mal den betreffenden Quellcodeteil komplett hin. Mit den Bruchstücken kann man nicht viel anfangen.

scp 14. Sep 2004 12:03

Re: Funktion aus der Dll aufrufen?
 
Vielleicht liegt es daran:
Delphi-Quellcode:
function VPUNK(t2:integer) : integer; external 'quelle.dll'; stdcall;
In der Regel werden DLL-Funktionen mit der Aufrufkonvention stdcall deklariert, sollte das auch nicht klappen kannst du es auch mal mit cdecl probieren.

egal 14. Sep 2004 12:09

Re: Funktion aus der Dll aufrufen?
 
Zitat:

Zitat von Luckie
Schreib mal den betreffenden Quellcodeteil komplett hin. Mit den Bruchstücken kann man nicht viel anfangen.

Delphi-Quellcode:
 
function VPUNK(t2:integer) : integer; external 'quelle.dll';

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
 var cPfad, c1 : string;
     a,t2: integer;
begin
  t2 := 3;
  a := VPUNK(t2);
  c1:= inttostr(a);
Ist so besser?

egal 14. Sep 2004 12:14

Re: Funktion aus der Dll aufrufen?
 
Zitat:

Zitat von scp
Vielleicht liegt es daran:
Delphi-Quellcode:
function VPUNK(t2:integer) : integer; external 'quelle.dll'; stdcall;
In der Regel werden DLL-Funktionen mit der Aufrufkonvention stdcall deklariert, sollte das auch nicht klappen kannst du es auch mal mit cdecl probieren.

Mit stdcall bekomme ich Fehlermeldungen:
Zitat:

[Fehler] Unit1.pas(27): Deklaration von 'VPUNK' unterscheidet sich von vorheriger Deklaration
, wenn stdcall am Ende von Funktionsdeklaration steht und wenn vor external, dann bekomme ich eine Zugriffsverletzung in meiner Dll.

Ultimator 14. Sep 2004 12:20

Re: Funktion aus der Dll aufrufen?
 
Das mit den unterschiedlichen Deklarationen kommt vermutlich daher, dass du stdcall sowohl oben als auch unten bei der procedur anschreiben musst, also so:
Delphi-Quellcode:
function VPUNK(t2:integer) : integer; external 'quelle.dll'; stdcall;
.
.
.
function VPUNK(t2:integer) : integer; external 'quelle.dll'; stdcall; // rufe diese funktion VPUNK auf.
t2: integer;
t2 := 3;
a := VPUNK(t2); // verwende sie.
Denk ich mal (ist zwar doof beschreiben, aber ich denke man sieht, was gemeint ist ;-) )

Hab mich verguckt, ist natürlich murks, was ich da geschrieben hab.
Du musst sowohl im Code der DLL ein stdcall; ranhängen als auch in der Unit, in der du sie verwendest.

Luckie 14. Sep 2004 12:20

Re: Funktion aus der Dll aufrufen?
 
Und jetzt noch die Funktion in der DLL und wie du sie exportiert hast. Dann kann man dir eventuell weiterhelfen.

egal 14. Sep 2004 12:25

Re: Funktion aus der Dll aufrufen?
 
Zitat:

Zitat von Ultimator
Das mit den unterschiedlichen Deklarationen kommt vermutlich daher, dass du stdcall sowohl oben als auch unten bei der procedur anschreiben musst, also so:
Delphi-Quellcode:
function VPUNK(t2:integer) : integer; external 'quelle.dll'; stdcall;
.
.
.
function VPUNK(t2:integer) : integer; external 'quelle.dll'; stdcall; // rufe diese funktion VPUNK auf.
t2: integer;
t2 := 3;
a := VPUNK(t2); // verwende sie.
Denk ich mal (ist zwar doof beschreiben, aber ich denke man sieht, was gemeint ist ;-) )

ich habe jetzt die ganze Quellcode angelegt, guck mal da bitte. Verstehe nicht ganz, wo muss ich stdcall noch einmal schreiben, wenn ich schon am Anfang bekomme meine Fehlermeldung.

egal 14. Sep 2004 12:29

Re: Funktion aus der Dll aufrufen?
 
Zitat:

Zitat von Luckie
Und jetzt noch die Funktion in der DLL und wie du sie exportiert hast. Dann kann man dir eventuell weiterhelfen.

die dll wurde mit Hilfe von Fortran-Compiler geschrieben, da muss man nur entsprechnede Befehle in command-line schreiben und er erstellt selber die Dll. Die Funktion wurde in Fortran geschrieben, hier ist die Quellcode:
Delphi-Quellcode:
        integer function vpunk(t)
         !DEC$ ATTRIBUTES DLLEXPORT :: vpunk
         integer t
         integer a,b
         a=2
         b=3
         vpunk = a*b+2-t
        end function vpunk

scp 14. Sep 2004 12:30

Re: Funktion aus der Dll aufrufen?
 
So sollte es gehen:
Delphi-Quellcode:
function VPUNK(t2:integer) : integer; stdcall;

implementation

{$R *.dfm}

function VPUNK(t2:integer) : integer; external 'quelle.dll'; stdcall; // rufe diese

egal 14. Sep 2004 12:36

Re: Funktion aus der Dll aufrufen?
 
Zitat:

Zitat von scp
So sollte es gehen:
Delphi-Quellcode:
function VPUNK(t2:integer) : integer; stdcall;

implementation

{$R *.dfm}

function VPUNK(t2:integer) : integer; external 'quelle.dll'; stdcall; // rufe diese

bekomme Zugriffsverletzungmeldung und Ergebnis ist auch falsch

egal 14. Sep 2004 12:39

Re: Funktion aus der Dll aufrufen?
 
Zitat:

Zitat von Ultimator
Hab mich verguckt, ist natürlich murks, was ich da geschrieben hab.
Du musst sowohl im Code der DLL ein stdcall; ranhängen als auch in der Unit, in der du sie verwendest.[/color]

Ich bin gar nicht sicher, dass es in Fortran auch stdcall gibt.

Dax 14. Sep 2004 13:00

Re: Funktion aus der Dll aufrufen?
 
Dann probier einfach alle Direktiven durch:
register, cdecl, pascal und safecall. Mehr kann der der Delphi-Compiler auch nicht.

egal 14. Sep 2004 13:22

Re: Funktion aus der Dll aufrufen?
 
Zitat:

Zitat von Dax
Dann probier einfach alle Direktiven durch:
register, cdecl, pascal und safecall. Mehr kann der der Delphi-Compiler auch nicht.

mit register bekomme ich wie früher den alten falschen Ergebnis, bei anderen dieselbe Fehlermeldung.

Dax 14. Sep 2004 13:25

Re: Funktion aus der Dll aufrufen?
 
In Delphi gibt es ja die MS-Calling-Convention __fastcall nicht, auch andere werden nicht unterstützt. Womöglich kompiliert FORTRAN deine DLL mit einer dieser nicht unterstützten und du merkst es nicht. Versuch doch mal, in FORTRAN die COnventions vorzugeben, dann brauchst du sie in Delphi nur noch abzuschreiben.

Muetze1 14. Sep 2004 13:57

Re: Funktion aus der Dll aufrufen?
 
Moin!

Laut dieser Website nutzt Fortran die cdecl Calling Convention. Also ist eigentlich nur dies das richtige.

Und wegen der Zugriffsverletzung: Ich hatte auch mal ein paar Fortran DLL Funktionen zu implementieren und diese haben alle bei Parameter einen Zeiger auf diesen erwartet. Also probier es zusätzlich mal aus den Aufrufparameter als Var zu deklarieren. Dazu musst du dann wahrscheinlich eine lokale Variable deklarieren für den Aufruf aber damit klappte es dann bei der Fortran DLL.

MfG
Muetze1

scp 14. Sep 2004 14:11

Re: Funktion aus der Dll aufrufen?
 
Also, ich habe auch mal durch die Quicktime API und anderes mit cdecl zu tun gehabt. Das ist auf jeden Fall etwas kniffeliger als die anderen und produziert auch schon mal AVs. Eine gute Lösung habe ich bis jetzt noch nicht gefunden, das mit den VAR-Parametern könnte aber durchaus hinhauhen.

EDIT:
Zitat:

Zitat von Assarbad's Tutorial
Bei allen Konventionen außer cdecl entfernt die Funktion die Parameter selbst vom Stack (in Delphi geschieht dies durch das Stackframe-Handling automatisch). Bei cdecl ist der Aufrufer dafür zuständig.

Heisst das man muss da extra ein paar Zeilen Code für schreiben, wenn ja was?

egal 14. Sep 2004 14:45

Re: Funktion aus der Dll aufrufen?
 
Zitat:

Zitat von Muetze1
Moin!

Laut dieser Website nutzt Fortran die cdecl Calling Convention. Also ist eigentlich nur dies das richtige.

Und wegen der Zugriffsverletzung: Ich hatte auch mal ein paar Fortran DLL Funktionen zu implementieren und diese haben alle bei Parameter einen Zeiger auf diesen erwartet. Also probier es zusätzlich mal aus den Aufrufparameter als Var zu deklarieren. Dazu musst du dann wahrscheinlich eine lokale Variable deklarieren für den Aufruf aber damit klappte es dann bei der Fortran DLL.

MfG
Muetze1

wo genau: in Fortran oder Delphi? Für Code wäre ich besonders dankbar! :mrgreen:

scp 14. Sep 2004 14:48

Re: Funktion aus der Dll aufrufen?
 
Generell beides: Wenn Fortran in cdecl exportiert musst du in Delphi auch in cdecl importieren.

egal 14. Sep 2004 14:58

Re: Funktion aus der Dll aufrufen?
 
:-D :-D :-D :-D :-D Endlich!!!!!!!!!!
Tatsächlich musste man nur var beim Aufrufparameter schreiben, mit stdcall funktioniert auch.

Allen vielen, vielen Dank!!!!!!!! :hello:

Assarbad 14. Sep 2004 15:42

Re: Funktion aus der Dll aufrufen?
 
Zitat:

Zitat von scp
Heisst das man muss da extra ein paar Zeilen Code für schreiben, wenn ja was?

@scp: Du kannst in Assembler nen Stub schreiben. Aber IMO ist das Overkill.

@egal: Du kannst auch CONST nehmen oder es als Pointer auf den entsprechenden Typen deklarieren. Ist alles im Tut beschrieben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:45 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