L'appel API Win32 spécifique de Delphi - Pourquoi exceptions Fly Sans un « pop asm ... »?

StackOverflow https://stackoverflow.com/questions/1093206

Question

J'utilise Delphi pour faire un XLL add-in pour Excel, ce qui implique de faire beaucoup d'appels à la balise fonction de Excel4v de xlcall32.dll. Cependant, comme je devine ici très peu d'experts Delphi ont travaillé avec cette API spécifique, j'espère que le problème aurait pu être observé dans d'autres API aussi.

En C, plus précisément dans le fichier xlcall.h qui vient avec le Microsoft Excel 2007 XLL SDK , Excel4v est défini comme suit:

int pascal Excel4v(int xlfn, LPXLOPER operRes, int count, LPXLOPER opers[]);

Dans Delphi J'utilise:

function Excel4v(xlfn: Integer; operRes: LPXLOPER; count: Integer;
    opers: array of LPXLOPER): Integer; stdcall; external 'xlcall32.dll';

LPXLOPER est un pointeur vers une structure (en C) ou un dossier (en Delphi).

Je fais mes devoirs sur la déclaration des fonctions C dans Delphi ( cet excellent article était une grande aide), et je pense que je déclare Excel4v correctement. Cependant, les appels à partir du code Delphi dans cette fonction des exceptions de cause ( "violation d'accès ..." est ce que je continue à voir) à moins qu'ils ne sont suivi par la ligne suivante:

asm pop sink; end;

Où « puits » est défini quelque part comme un entier.

Je n'ai pas la moindre idée de montage ... Donc, il n'y a aucun moyen aurais-je pensé à essayer fixant les exceptions avec « puits pop asm, fin; ». Mais "évier pop asm, fin;" ne résout en effet les exceptions. Je l'ai vu utilisé dans cet article utile à rendre XLLs en utilisant Delphi . Voici la citation la plus pertinente:

  

"De Delphi le grand bloc de trébuchement   avec des add-ins est le paramètre supplémentaire   après l'adresse de retour sur la pile.   Cela est livré gratuitement avec chaque appel   Exceller. Je ne l'ai jamais trouvé ce qu'il   Peut contenir, mais aussi longtemps que vous jetez   loin, votre complément fonctionnera bien. Ajouter   la variable de ligne de pop asm, fin; après   chaque appel où peut être une variable   global, variable locale ou un objet   est d'au moins 4 octets entier long est   bien. Pour REPEAT- DOIT ÊTRE INCLUS CE   après chaque appel Excel4v. Autrement   vous construisez une bombe à retardement. "

En gros Je veux comprendre ce qui se passe réellement, et pourquoi . Ce qui pourrait être à l'origine d'une fonction Win32 pour retourner un « paramètre supplémentaire après l'adresse de retour sur la pile », et qu'est-ce que cela signifie réellement?

Y aurait-il une autre façon de résoudre ce problème, par exemple avec une option de compilateur différent ou une autre façon de déclarer la fonction?

Et il n'y a rien risqué à appeler « évier pop asm, fin; » après chaque appel à Excel4v ...? Il semble fonctionner très bien, mais, comme je ne comprends pas ce qui se passe, il se sent un peu dangereux ...

Était-ce utile?

La solution

Je ne crois pas que ce soit pascals vs stdcall - Ce sont des conventions d'appel très similaires et ne devraient pas entraîner une pile à la sortie de mal apparié fonction

.

De la article ,

  

Ce serait en effet une très belle   syntaxe, mais ce n'est pas le même que le   définition du tableau ci-dessus. Tableau de   les paramètres sont des paramètres tableau ouvert.   Ils peuvent ressembler à tout tableau, et ils   faire accepter tout tableau, mais ils obtiennent une   paramètre supplémentaire (caché), qui contient   l'indice le plus élevé dans le réseau (le   Haute valeur). Comme il ne l'est que dans   Delphi, et non en C ou C ++, vous devriez   un vrai problème. (Voir aussi mon   article sur les tableaux ouverts), depuis le   nombre de paramètres réels ne serait pas   correspondance.

Vous obtenez le paramètre supplémentaire « plus haut indice de tableau » étant passé à la fonction. Ceci est un entier et doit être nettoyé lorsque la fonction sort de telle sorte que vous ne liquidez pas avec une pile endommagée et accident. L'article indique comment passer des tableaux aux fonctions C.

Quelque chose comme:

type
 PLPXLOPER  = ^LPXLOPER;

Et passer PLPXLOPER comme le dernier paramètre.

Autres conseils

La plupart des fonctions Windows, utilisez __stdcall conventions d'appel .

Votre convention d'appel est erroné, en particulier la "stdcall". La déclaration C est spécifiée comme « pascals »

STDCALL transmet les paramètres à droite à l'ordre gauche, attend la routine pour nettoyer, et ne pas utiliser les registres. Pascal, OTOH transmet les paramètres dans gauche à droite commande. Par conséquent, les choses ne se passent pas la façon dont l'autre moitié du code prévoit que dans les deux cas.

Changer votre déclaration Delphi aussi être "pascals" au lieu de "stdcall".

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top