2009-10-29 2 views
1

J'accès à une DLL par:FAR par rien et par PASCAL __stdcall

int (__stdcall *Send) (char *); 
Send = (int (__stdcall *)(char *)) GetProcAddress(hmModule,"Send"); 

L'appel initial utilise:

int (FAR PASCAL *Send) (char FAR *); 
Send = (int (FAR PASCAL *)(char FAR *))GetProcAddress(hmModule,"Send"); 

Y at-il inconvénient de remplacer FAR par rien et par PASCAL __stdcall

Répondre

3

La suppression de FAR peut imposer à tous les modules d'être dans le même segment. C'est probablement bien si c'est un petit programme.
Editer: FAR est cependant une relique du passé et ne s'applique pas aux cibles win32, et peut être supprimée dans la plupart des cas.

La modification de la convention d'appel n'affecte que l'interopérabilité possible avec des modules externes appelant ces méthodes. (il peut aussi avoir des effets sur la performance, mais je ne suis même pas sûr de cela).

Modifier: MAIS WOW ...! Non! ne peut pas être fait, Je n'ai pas remarqué que c'était pour une méthode WinAPI, c'est-à-dire un quand la convention d'appel a été facilement définie pour vous ... et la même chose vaut probablement pour FAR, il est probablement nécessaire.

lendemain modifier, avec hya, des détails supplémentaires de l'OP
La fonction cible est définie dans Windef.h comme

extern "C" int APIENTRY Send (LPCSTR sCmd) 

Avec son soutien à de très nombreux systèmes d'exploitation, les versions du compilateur et des valeurs définies localement , windef.h est [assez assez] un exercice de logique combinatoire. Avec la plupart des chemins [non MAC], et en supposant Windef.h est relativement stable dans ce domaine, APIENTRY se résume à

... 
#define APIENTRY WINAPI 
... 
#define WINAPI __stdcall 

Et puisque pour les mêmes chemins, PASCAL produit également le premier __stdcall « mystère » est résolu, dans ce contexte particulier (ie généralement non MAC, compilateur MSC 8.0 ou supérieur (ou un compilateur définissant _STDCALL_SUPPORTED ...)

En ce qui concerne FAR ou rien, c'est moins clair (pour moi), mais aussi , la plupart des chemins dans les macros windef.h conduisent à ces deux macros comme ne produisant rien, je pense que c'est parce que le compilateur utiliserait la cible modèle de mémoire pour comprendre ce qui était des pointeurs courts et longs. Quoi qu'il en soit, le prototype cible utilise LPCSTR, c'est-à-dire un pointeur "long/long" et c'est probablement ce que le compilateur a produit. De même pour le modificateur FAR utilisé avec la fonction elle-même, ceci n'est pas nécessaire non plus, le compilateur talonnant pour un appel éloigné selon le modèle de mémoire et/ou implicitement.

Donc, ce qui précède explique pourquoi, YES, les modifications apportéesPASCAL-__stdcall et de FAR à rien sont OK et devrait se traduire par une binaire fonctionnelle. (probablement à re-vérifier etc, si vous changez le compilateur et/ou le système d'exploitation cible).

Merci pour cette question, car cela m'a incité à revoir les problèmes que je n'avais pas vu depuis un moment.

+0

Passer de PASCAL à StdCall n'aura aucun préjudice de performance, comme si la DLL était compilée pour permettre StdCall (qui le sont le plus) alors il n'y aurait aucune différence d'accès. Espérons qu'il comprend que FAR se réfère à une adresse située dans un segment différent de l'origine des pointeurs définis. – Reallyethical

+0

@ Reallyethical, à droite, merci de confirmer la différence de performance, et tout OK sur FAR. Je suis un peu perplexe quant aux besoins exacts de l'OP etc. Vous avez raison la plupart des API utilisent __stdcall (aka WINAPI), mais l'implication que je reçois de la question est que cela fonctionne actuellement, donc en changeant la convocation d'appel. Je casserais définitivement les choses ... Peut-être que je manque quelques ' – mjv

+0

Cet après-midi quand j'ai eu la DLL, j'ai cherché un exemple de travail et en ai trouvé un en C avec l'ancien appel FAR PASCAL. Je suspecte que le code a été écrit pour une version antérieure de la DLL. Je l'ai juste regardé la source et APIENTRY (=> WINAPI => __ stdcall) est utilisé: extern "C" int APIENTRY Envoyer (LPCSTR SCMD) En Windef.h PASCAL est défini comme __stdcall, il explique pourquoi les deux travaillent (?). – anno