Autor |
Beitrag |
presswurst
Hält's aus hier
Beiträge: 11
|
Verfasst: Mi 11.07.07 15:07
Hallo Community!
Heute habe ich mal ein bisschen mit DLL-Files (also externen Funktionen) herumgespielt.
Der Code dazu sah dann so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| implementation procedure pnum(num : integer); external 'erstertest.dll'; {$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); begin pnum(444); end;
end. |
Der Code der datei 'erstertest.dll' ist Folgender:
Quelltext 1: 2: 3: 4: 5: 6:
| DLLIMPORT void pnum(int num) { char x[20];
sprintf(x, "%i", num); MessageBox(0, x, "pnum(int)", MB_ICONINFORMATION); } |
Fuer leute die mit C nichts am Hut haben:
Diese Funktion wandelt den mit pnum uebergebenen Integer (also 444) in einen Ascii-String um und gibt ihn in einer MessageBox aus.
Das Problem an der Sache ist jetzt aber dass es schlicht und einfach nicht funktioniert. Erkennt jemand vllt was ich falsch gemacht hab? Darf ich die C-Funktion nicht als procedure deklarieren? (Ich dachte Delphi-Prozeduren kommen void-Funktionen gleich, sie waeren wie Funktionen ohne Rueckgabewert)
Danke schonmal
lg, presswurst
PS: Hoffentlich habe ich jetzt endlich mal auf anhieb das richtige Forum fuer meinen Thread gefunden, ist nicht boes gemeint aber offenbar finde ich mich hier nur ein bisschen schwerer zurecht
Moderiert von Gausi: Delphi-Tags hinzugefügt
Zuletzt bearbeitet von presswurst am Mi 11.07.07 15:26, insgesamt 1-mal bearbeitet
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mi 11.07.07 15:12
Hallo und  in der Entwickler-Ecke,
Auf Anhieb fällt mir nur auf, dass du ein var zu viel in der OnClick-Prozedur hast. Der Compiler erwartet danach dann die Deklaration von lokalen Variablen für diese Prozedur, aber du legst direkt mit begin los.
_________________ We are, we were and will not be.
|
|
presswurst 
Hält's aus hier
Beiträge: 11
|
Verfasst: Mi 11.07.07 15:24
Gausi hat folgendes geschrieben: | Hallo und in der Entwickler-Ecke |
Danke
Gausi hat folgendes geschrieben: | Auf Anhieb fällt mir nur auf, dass du ein var zu viel in der OnClick-Prozedur hast. Der Compiler erwartet danach dann die Deklaration von lokalen Variablen für diese Prozedur, aber du legst direkt mit begin los. |
Das ist richtig, in der Version die ich hier habe hatte ich einige Variablen Deklariert die ich dann in meinem Post entfernt habe (auch den Code aus dem onclick-event der nichts mit der pnum-Prozedur zu tun hatte habe ich entfernt), man will es ja auf das noetigste reduzieren
das var werde ich mal in meinem Post entfernen, nicht dass es noch mehr verwirrung anrichtet *g* - Danke fuer den Hinweis!
lg, presswurst
PS: Wie lauten denn die Tags fuer das schoene Syntax-Highlighting das du in meinen Thread hineineditiert hast? 
Zuletzt bearbeitet von presswurst am Mi 11.07.07 15:28, insgesamt 1-mal bearbeitet
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 11.07.07 15:25
Du schreibst in C eine Funktion. Als Standard nutzt diese die Aufruf-Konvention stdcall und erwartet daher die Parameter auf dem Stack.
Im Delphi-Source deklarierst Du diese Funktion aber mit der Aufruf-Konvention register, welche die Argumente in den CPU-Registern sofern möglich übergibt. Ergänz einfach noch ein stdcall in der Deklaration der Funktion unter Delphi, dann sollte es gehen ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
presswurst 
Hält's aus hier
Beiträge: 11
|
Verfasst: Mi 11.07.07 16:13
So wie es aussieht lag es genau daran, danke
Also um es nochmal zusammenzufassen: Wenn Delphi kein stdcall in seiner Funktionsdeklaration hat dann sucht es sich selbst aus ob die Argumente auf Registern oder ueber den Stack uebergeben werden?
Wie mir scheint verlangt Delphi im falle eines stdcall auch dass die aufgerufene Funktion den Stack von selbst bereinigt was im falle _eines_ 4-byte Argumentes heisst dass ich die Funktion mit 'ret 4' anstatt mit 'ret' verlassen muss.
lg, presswurst
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 11.07.07 17:58
presswurst hat folgendes geschrieben: | So wie es aussieht lag es genau daran, danke  |
Ist einer der Standard-Fehler bei C-DLLs ...
presswurst hat folgendes geschrieben: | Also um es nochmal zusammenzufassen: Wenn Delphi kein stdcall in seiner Funktionsdeklaration hat dann sucht es sich selbst aus ob die Argumente auf Registern oder ueber den Stack uebergeben werden? |
Nein. Ohne übergibt Delphi die Argument in den CPU-Registern. Näheres findest Du in der Delphi-Hilfe unter stdcall bzw. bei den Aufrufkonventionen.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
presswurst 
Hält's aus hier
Beiträge: 11
|
Verfasst: Fr 13.07.07 22:03
BenBE hat folgendes geschrieben: | Nein. Ohne übergibt Delphi die Argument in den CPU-Registern. Näheres findest Du in der Delphi-Hilfe unter stdcall bzw. bei den Aufrufkonventionen. |
Danke fuer das Stichwort - genau das war es was ich gesucht habe. Noch besser wird es wohl mit 'cdecl' gehen, so ueberlasse ich das mit dem stack mal dem Delphi-Compiler und kann in meinem C-Code auf '__stdcall' verzichten. Auch wenn es sinnlos im bezug auf Delphi ist habe ich mir im laufe der Zeit angewoehnt C90-konform zu programmieruen.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Fr 13.07.07 22:30
In C ist stdcall unter Windows standard. D.h. __stdcall müsste schon so weggelassen werden können, ähnlich wie register unter Delphi... Im Allgemeinen hat es sich eingebürgert unter Windows C-Libs mit stdcall zu compilieren. Das ist nämlich das erste, was die meisten probieren, wenn die Aufrufkonvention nicht gegeben ist.
Sei denn, Du brauchst unbedingt VarArgs in C (wovon man eh nicht gebrauch machen sollte ...)
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
|