Autor Beitrag
Tactive
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Sa 23.11.02 03:26 
Hallo,

ich schreibe gerade unter C/C++ eine DLL die ich per Delphi benutzen möchte. Nun habe ich eine Funktion die per Pointer einen Wert zurückgeben soll.

In der C/C++ DLL sieht das so aus:

ausblenden Quelltext
1:
2:
3:
4:
5:
SAMLOAD_API bool SAM_CreateNewArchieve__1(DWORD *dwIDArchieve)
{
    (*dwIDArchieve) = 45;
    return true;
} // SAM_CreateNewArchieve


In meinem Delphi Projekt habe ich in einer Klasse jetzt folgendes:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
type
  DWORDPTR = ^Longword;

type
  SAMLoad = class
  public
    function  CreateNewArchieve(NewArchieveID: DWORDPTR) : boolean;
  end;

implementation

function  SAMLoad.CreateNewArchieve;
external  'samload.dll' name 'SAM_CreateNewArchieve__1';


Um das ganze nun zu testen habe ich in einer andere Klasse
folgende Aufruf:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var
  tst : Longword;
  txt : String;
begin
  Sam.CreateNewArchieve(@tst);
  txt := IntToStr(tst);
  ShowMessage(txt);
end;


Eigendlich müsste in 'txt' doch nun die 45 stehen, aber leider bekomme ich immer nur 1 als Ergebnis. Was mache ich falsch ??


[/code]
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Sa 23.11.02 13:29 
wenn das der Code aus deinem Programm ist, könnte folgendes der Fehler sein:
du shcreibst in der Deklaration:
ausblenden Quelltext
1:
function  CreateNewArchieve(NewArchieveID: DWORDPTR) : boolean;					


aber in der Implementation dieser Funktion nur
ausblenden Quelltext
1:
function  SAMLoad.CreateNewArchieve;					


Fazit: Es gibt eine deklarierte Funktion, die nirgendswo implementiert ist. Zusätzlich gibt es eien implementierte Funktion, die nirgendswo deklariert ist. Normalerweise sollte Delphi dir das gleiche Erzählen, wieich gerade, aber falls nicht, probier's mal so:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
type
  DWORDPTR = ^Longword;

type
  SAMLoad = class
  public
    function  CreateNewArchieve(NewArchieveID: DWORDPTR) : boolean;
  end;

implementation

function  CreateNewArchieve(NewArchieveID: DWORDPTR) : boolean;
external  'samload.dll' name 'SAM_CreateNewArchieve__1';


Jetzt müsste es funktionieren.

Ach ja, du sparst dir eine Variable, wenn du in deiner anderen Klasse "zum testen" folgendes machst:
ausblenden Quelltext
1:
2:
  Sam.CreateNewArchieve(@tst);
  Showmessage(IntToStr(tst));

Schon kannst du dir txt sparen...

Ob der C++-Teil Fehler enthält, weiß ich mangels C-Wissen nicht. :-(

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Sa 23.11.02 15:08 
Hallo Tactive!

Ich kenne mich mit C auch nicht aus, aber soweit ich weiss, ist es wichtig das man bei der Funktiondeklaration ein stdcall anhängt. Versuch's mal so:
ausblenden Quelltext
1:
2:
  function  SAMLoad.CreateNewArchieve; 
external  'samload.dll' name 'SAM_CreateNewArchieve__1'; stdcall;
Gruß wulfskin!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
Tactive Threadstarter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mo 25.11.02 01:20 
Vielen Dank für Eure Hilfe aber klappt leider beides nicht. Wenn ich das mit dem 'stdcall' einbaue dann schmiert mir das Programm sogar mit einer Fehlermeldung ab. Verstehe das alles auch irgendwie nicht.

Muss aber dazu sagen das ich erst seit kurzem mit Delphi programmiere. Habe mich die letzten 2-3 Jahre mit C/C++ beschäftigt.
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 25.11.02 11:56 
wulfskin hat folgendes geschrieben:
... aber soweit ich weiss, ist es wichtig das man bei der Funktiondeklaration ein stdcall anhängt.

Tactive hat folgendes geschrieben:
Wenn ich das mit dem 'stdcall' einbaue dann schmiert mir das Programm sogar mit einer Fehlermeldung ab.

Ich empfehle zu dem Thema das DLL-Tutorial von Assarbad:
Zitat:
Das enthaltene Beispielprogramm zeigt einmal kurz, wie es sich auswirken kann, wenn man die Aufrufkonventionen nicht beachtet. Einfach mal etwas rumspielen, aber bitte beachten, daß unter Windows 9x durchaus ein Systemabsturz anstehen könnte ...

Wenn ich mir die typische Arbeit des Assistenten vom VS6 ansehe, dann wird dort wie folgt deklariert:
ausblenden Quelltext
1:
#define SAMLOAD_API __declspec(dllexport)					

Die Namensähnlichkeit verleitet mich zu der Annahme, dass als Aufrufkonvention hier nicht stdcall sondern vielleicht eher cdecl verwendet werden müsste. Aber ich kann mich auch irren. Nur, meine Annahme würde auch dem Zitat aus Assarbads Tutorial entsprechen: wenn ich die Aufrufkonvention nicht beachte, kann das Programm oder sogar das System abstürzen.

So, jetzt aber -
Brauchst du unbedingt eine Klasse für die Funktion? Ausgehend von einem ähnlichen Beispiel aus dem PSDK und der Borland-Übersetzung nach Delphi hätte ich folgendes vorgeschlagen:
ausblenden Quelltext
1:
2:
function CreateNewArchieve(out NewArchieveId: cardinal): boolean;
  external 'samload' name 'SAM_CreateNewArchieve__1';


Ich hätt´s gern ausprobiert und dir lieber ein erfolgreiches Posting geschrieben, aber - ich habe heute spaßeshalber meine allererste DLL mit dem Visual Studio 6 erstellt. Nur, als ich sie in Delphi verwenden wollte, erschien die unschöne Meldung:
Zitat:
Die Datei XY ist verknüpft mit dem fehlenden Export ABC

Obwohl ich eine Standard-DLL benutzt habe, die der Assistent vom VS6 bereits mit einer Beispielfunktion versehen hatte. :cry: