9
votes

Delphi cette convention appelante

J'ai besoin d'appeler des fonctions de membre non statiques C ++

J'ai donc besoin d'utiliser le CeciCall code> Convention d'appel. P>

Delphi ne prend pas en charge cette convention appelante.

Donc avant que je puisse appeler l'une des fonctions de membre, je dois appuyer manuellement les paramètres de la pile. P>

  asm
    mov ecx, myClassPointer
  end;


1 commentaires

J'ai écrit une partie CeciCall adaptateurs pour les interfaces Rich-Edit de Microsoft , qui incorrectement omis les conventions appelantes. Mes adaptateurs enveloppent des interfaces dans les deux sens, le code Delphi peut donc appeler le code de Microsoft et le code de Microsoft peut rappeler à une interface Delphes, et chaque partie pense que l'autre fournit la convention d'appel attendue. Peut-être que vous le trouveriez utile.


3 Réponses :


5
votes

Vous avez les options suivantes:

  • Écrivez des adaptateurs dans ASM pour appeler la fonction. Ceci est votre solution actuelle et comme vous savez que l'approche est fragile et gênante.
  • Écrivez un adaptateur C ++ qui présente une interface conviviale interoper.

    La dernière option est, à mon avis, la solution correcte. Le code C ++ ne convient pas à Interop. Exposer les classes C ++ par Interop est tout simplement fausse. Il place des demandes déraisonnables sur le consommateur. Les approches raisonnables incluent l'INTEROP COM et CLAIR C STOCTÉ COMMUNIQUÉ dans WIN32.

    Écrivez une DLL ADAPTATION C ++ qui consomme les classes C ++ déraisonnables et expose une interface intéressante appropriée. L'adaptateur est écrit en C ++ et est donc capable de consommer le code C ++. Mais ensuite, il exporte une variante interopté de l'interface qui peut être appropriée à partir de n'importe quelle chaîne d'outils.


3 commentaires

Pourriez-vous s'il vous plaît élaborer la partie des adaptateurs. Je n'ai jamais entendu parler de cela dans les terminaux de la fonction Delphes appelant. Fondamentalement, il devrait appeler le code ASM avec le pointeur de classe souhaité avant d'appeler la fonction / la procédure elle-même.


Non, l'adaptateur n'est une couche entre l'original CeciCall C ++ et votre code Delphi. Il peut appeler le CeciCall C ++ et le réexporte en tant qu'interface de sécurité interopté appropriée.


Voir l'article que j'ai mentionné dans Ma réponse . Il décrit largement le code de l'adaptateur.



3
votes

Comme David l'a déjà dit, vous pouvez continuer à utiliser Assembler, mais il y a de meilleurs moyens. J'ai écrit un article appelé "Utilisation d'objets C ++ dans Delphi" qui décrivent largement. , avec code, comment utiliser les deux alternatives viables:

  • Écrivez une couche C qui exporte des fonctions de style C qui utilisent simplement la classe C ++ et exposer à chacune des méthodes comme des fonctions simples. C'est assez simple, mais un peu maladroit à utiliser du côté Delphi.
  • Écrivez une couche COM, ce qui n'est pas aussi facile que cela sonne. J'avais besoin d'une certaine aide d'un gourou C ++ pour le faire correctement. L'article décrit les étapes et vous pouvez les appliquer 1 à 1 à votre classe (ES).

    Je préférerais personnellement la com-couche. Il est beaucoup plus facile d'utiliser du côté Delphi.

    L'article décrit également quelques problèmes que vous pouvez rencontrer lors de la rédaction de ce code ou de l'utilisation de tels objets. Lisez tout cela.


0 commentaires

4
votes

Delphi's registre Convention d'appel utilise des registres pour les trois premiers paramètres. Les deux premiers sont eAx et edx , qui sont inutilisés dans la convention CeciCall et peuvent être définis sur tout ce que vous voulez. Le troisième de ces registres est ECX .

CeciCall passe tous les arguments sur la pile et registre passe des arguments restants sur la pile. enregistrer et thiscall ont les arguments de nettoyage de callee transmis sur la pile.

Donc, ce que vous pouvez faire est de déclarer une fonction enregistrer , avec des paramètres factices pour EAX et edx . Vous pouvez toujours envelopper cela dans une fonction différente pour faciliter l'appel, mais au moins maintenant que la fonction wrapper peut être déclarée en ligne . .

Notez que l'ordre dans lequel les arguments sont poussés sur la pile est différent entre CeciCall et enregistrer , vous devez donc inverser les paramètres pour correspondre.


0 commentaires