Quote:
Je suis très intéressé pour avoir plus d'information à ce sujet puisque je ne trouve rien dans l'aide Delphi sur ce protocole spécifique !
C'est dans la doc sans aucun doute. Je ne sais plus où car j'ai désintallé mes Delphi depuis bien longtemps. Mais en cherchant des mots-clés comme pascal, cdecl ou stdcall tu vas forcément trouver.
De mémoire je dirais qu'il y a 5 conventions d'appels possibles en Delphi. register, pascal, cdecl stdcall et safecall
Par défaut Delphi utilise register il me semble. Et obligatoirement pour les propriétés publiques des objets. Mais mieux vaut oublier register qui risque de ne pas faire bon ménage avec d'autres langages. On oublie aussi le très particulier safecall qui concerne les appels COM Windows
Soit une fonction: fonction(arg1, arg2)
pascal:
pousse les paramètres sur la pile de gauche à droite. arg1, puis arg2. C'est le code de la fonction qui réajuste le pointeur de pile.
cdecl:
pousse les paramètres sur la pile de gauche à droite. arg2, puis arg1. C'est le code appelant la fonction qui réajuste le pointeur de pile.
cdecl est la convention d'appel normal en C et C++ sauf si ça a été compilé autrement...
stdcall
pousse les paramètres sur la pile de gauche à droite. arg2, puis arg1. C'est le code de la fonction qui réajuste le pointeur de pile.
stdcall est la convention des API Windows
Donc s'il s'agit d'appeler du code C ou C++ la fonction (protoype) à appeler doit être déclarée cdecl (cf doc) dans le code Delphi.
Du C pas de problème. Du C++, si la fonction à appeler a été déclarée extern "C" pas de problème. Sinon le nom de la fonction C++ est décoré et l'éditeur de lien de Delphi ne va pas la trouver. Le mieux dans ce cas est d'écrire un stub C++ avec le même compilateur qui a été utilisé pour compiler la librairie (toujours le problème de la décoration, il faut cette fois que ce soit l'éditeur de lien C++ qui puisse le trouver, ce qui ne posera pas de pb si le compilateur est le même)
S'il s'agit d'appeler une API Windows il faut déclarer stdcall le prototype de la fonction côté Delphi.
Quote:
D'autant plus que dans mon cas, j'ai une procédure en paramètre à envoyer qui elle-même contient 2 paramètres (un PChar et un integer).
Dans tous les cas y compris celui-ci, il faut s'assurer que les types font la même taille dans les deux langages. Il ne s'agit donc pas de passer un PChar ou un integer mais de passer quelque chose qui à la même taille que ce à quoi s'attend le code C ou C++. Même remarque pour une éventuelle valeur de retour.
Dans le cas particulier de la procédure à passer il peut y avoir des difficultés supplémentaires
- qu'est-ce qui est attendu côté C ? S'il s'agit de passer une fonction de rappel c'est peut être la convention stdcall qui est attendue. Le cas est fréquent.
- les procédures (beurk) n'ont pas de valeur de retour. Donc le code va à priori modifier des paramètres reçus par référence. Si c'est le cas ça doit aller. Si le code travaille avec des variables globales, des mauvaises surprises ne sont pas exclues.
C'est dans la doc sans aucun doute. Je ne sais plus où car j'ai désintallé mes Delphi depuis bien longtemps. Mais en cherchant des mots-clés comme pascal, cdecl ou stdcall tu vas forcément trouver.
De mémoire je dirais qu'il y a 5 conventions d'appels possibles en Delphi. register, pascal, cdecl stdcall et safecall
Par défaut Delphi utilise register il me semble. Et obligatoirement pour les propriétés publiques des objets. Mais mieux vaut oublier register qui risque de ne pas faire bon ménage avec d'autres langages. On oublie aussi le très particulier safecall qui concerne les appels COM Windows
Soit une fonction: fonction(arg1, arg2)
pascal:
pousse les paramètres sur la pile de gauche à droite. arg1, puis arg2. C'est le code de la fonction qui réajuste le pointeur de pile.
cdecl:
pousse les paramètres sur la pile de gauche à droite. arg2, puis arg1. C'est le code appelant la fonction qui réajuste le pointeur de pile.
cdecl est la convention d'appel normal en C et C++ sauf si ça a été compilé autrement...
stdcall
pousse les paramètres sur la pile de gauche à droite. arg2, puis arg1. C'est le code de la fonction qui réajuste le pointeur de pile.
stdcall est la convention des API Windows
Donc s'il s'agit d'appeler du code C ou C++ la fonction (protoype) à appeler doit être déclarée cdecl (cf doc) dans le code Delphi.
Du C pas de problème. Du C++, si la fonction à appeler a été déclarée extern "C" pas de problème. Sinon le nom de la fonction C++ est décoré et l'éditeur de lien de Delphi ne va pas la trouver. Le mieux dans ce cas est d'écrire un stub C++ avec le même compilateur qui a été utilisé pour compiler la librairie (toujours le problème de la décoration, il faut cette fois que ce soit l'éditeur de lien C++ qui puisse le trouver, ce qui ne posera pas de pb si le compilateur est le même)
S'il s'agit d'appeler une API Windows il faut déclarer stdcall le prototype de la fonction côté Delphi.
Dans tous les cas y compris celui-ci, il faut s'assurer que les types font la même taille dans les deux langages. Il ne s'agit donc pas de passer un PChar ou un integer mais de passer quelque chose qui à la même taille que ce à quoi s'attend le code C ou C++. Même remarque pour une éventuelle valeur de retour.
Dans le cas particulier de la procédure à passer il peut y avoir des difficultés supplémentaires
- qu'est-ce qui est attendu côté C ? S'il s'agit de passer une fonction de rappel c'est peut être la convention stdcall qui est attendue. Le cas est fréquent.
- les procédures (beurk) n'ont pas de valeur de retour. Donc le code va à priori modifier des paramètres reçus par référence. Si c'est le cas ça doit aller. Si le code travaille avec des variables globales, des mauvaises surprises ne sont pas exclues.