Autor Beitrag
presswurst
Hält's aus hier
Beiträge: 11



BeitragVerfasst: 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:

ausblenden 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:

ausblenden 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 user profile iconGausi: Delphi-Tags hinzugefügt


Zuletzt bearbeitet von presswurst am Mi 11.07.07 15:26, insgesamt 1-mal bearbeitet
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Mi 11.07.07 15:12 
Hallo und :welcome: 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 Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Mi 11.07.07 15:24 
user profile iconGausi hat folgendes geschrieben:
Hallo und :welcome: in der Entwickler-Ecke


Danke :)



user profile iconGausi 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mi 11.07.07 17:58 
user profile iconpresswurst hat folgendes geschrieben:
So wie es aussieht lag es genau daran, danke :)

Ist einer der Standard-Fehler bei C-DLLs ...

user profile iconpresswurst 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 Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Fr 13.07.07 22:03 
user profile iconBenBE 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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.