[C] accéder à une zone de mémoire allouée en dehors d'une DLL

accéder à une zone de mémoire allouée en dehors d'une DLL [C] - C - Programmation

Marsh Posté le 07-08-2008 à 18:15:54    

Bonjour à tous,

 

Je travaille sur une appli structurée ainsi :

 

appli <--> DLLprincipale <--> DLLutilisateur

 


La majeure partie du code de l'appli est dans la DLL principale. Il y a une bibliothèque que l'utilisateur peut écrire et compiler lui-même pour récupérer le résultat de son calcul perso.

 

j'appelle donc cette fonction depuis la DLLprincipale :

 


Code :
  1. int CalculerVariableUtilisateur(float x, float y, float z, float *pR, int nbVar,
  2.        int i, int j, int k, int numVar, float *pV)
 


où tous les paramètres sont des entrées sauf le dernier, pV qui est le résultat du calcul.
l'int de retour est un code erreur.

 

Ce pointeur pV pointe sur un tableau alloué dans la DLL principale.

 

Dans la DLL utilisateur on fait :

 
Code :
  1. *pV = x+y;
 

par exemple.

 

et voici l'appel :

 
Code :
  1. codeErreur = CalculerVariableUtilisateur((*pP)[0], (*pP)[1], (*pP)[2],
  2.                                                          pRU, nbVarU,
  3.                                                          i+1, j+1, k+1,
  4.                                                          numVarU,idDomain, pV);
 


Le souci c'est que l'appel de cette fonction me donne ceci vu depuis la lib utilisateur:

 
Code :
  1. CalculerVariableUtilisateur(x = 10.0, y = 0.0, z = 10.0, pR = 0x10252b4c0, nbVar =
  2. 5, i = 1, j = 1, k = 1, numVar = 6, pV = 0x1)
 

l'adresse de pV est bidon. Pourtant la fonction est correctement appelée, la mémoire correctement allouée. Et ca plante, évidement. Pourtant pR a bien une adresse correcte... c'est à n'y rien comprendre.

 

Je me demande si ce n'est pas un souci de flags de compilation et une sombre histoire de pile et de tas. Ou de dépassement mémoire, pourtant j'ai déjà recherché les fuites.


Message édité par kaloskagatos le 08-08-2008 à 10:16:25

---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 07-08-2008 à 18:15:54   

Reply

Marsh Posté le 07-08-2008 à 18:28:14    

problème de convention d'appel de la fonction, peut-être ?

Reply

Marsh Posté le 07-08-2008 à 18:31:16    

Qu'est-ce que tu entends par convention d'appel?

  

edit: ok je pense que c'est un domaine que je ne connais pas, j'y jette un coup d'oeil.


Message édité par kaloskagatos le 07-08-2008 à 18:35:41

---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 07-08-2008 à 19:36:27    

Je doute que ça soit un problème de convention d'appel. Ta fonction doit certainement être un callback, si ce callback n'utilise pas la même convention d'appel, tu auras une erreur à la compilation (sauf si tu cast à l'arrache avec un void *).
 
À vu de nez, ça sent la mauvaise utilisation d'une API et/ou buffer overflow.

Reply

Marsh Posté le 08-08-2008 à 10:12:20    

Le truc que je capte pas c'est que le paramètre "foat *Pr" qui est une entrée peut être modifié/accédé, alors que "float *pV" qui est alloué de la même manière est dans les choux :/


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 08-08-2008 à 12:44:08    

tpierron a écrit :

Je doute que ça soit un problème de convention d'appel. Ta fonction doit certainement être un callback, si ce callback n'utilise pas la même convention d'appel, tu auras une erreur à la compilation (sauf si tu cast à l'arrache avec un void *).
 
À vu de nez, ça sent la mauvaise utilisation d'une API et/ou buffer overflow.


 
pas nécessairement, si la convention n'a pas été précisée explicitement dans les header, elle est déterminée par tes options de compilation. Du coup, à l'utilisation si ton projet n'a pas la même convention que celle spécifiée par la DLL, tu ne vois rien à la compilation.
 
Jette donc toujours un coup d'oeil aux stdcall fastcall et cdecl et vérifie, si tu peux, comment est compilée la DLL

Reply

Marsh Posté le 08-08-2008 à 13:25:08    

Est-ce que vous savez si la valeur du pointeur à 0x1 correspond à un code erreur du noyau?


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 08-08-2008 à 13:31:47    

l'appli est compilée en utilisant ce header :
 

Code :
  1. extern "C" int CalculerVariableUtilisateur(float  /* x  : IN */,
  2.            float  /* y  : IN */,
  3.            float  /* z  : IN */,
  4.            float * /* pR  : IN */,
  5.            int  /* nbVar : IN */,
  6.            int  /* i  : IN */,
  7.            int /* j  : IN */,
  8.            int  /* k  : IN */,
  9.            int  /* numVar : IN */,
  10.            int      /* idDomain     : IN */,
  11.            float * /* pV  : OUT */);


 
la DLL utilise :
 

Code :
  1. int CalculerVariableUtilisateur(float x, float y, float z, float *pR, int nbVar,
  2.        int i, int j, int k, int numVar, float *pV)


 
 
Je ne vois absolument aucun flag à la compilation qui pourrait gêner.


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 08-08-2008 à 14:39:36    

les codes d'erreur du kernel, sous windows, sont négatifs lorsque considérés comme int, donc 1 n'est probablement pas un code d'erreur (d'autant plus que je ne vois pas ce qui justifierais son apparition miraculeuse dans une variable comme c'est le cas pour toi en ce moment)
 
Pour tes headers, comme je le pensais, les conventions ne sont pas données clairement.
Cherche un peu dans les propriétés de tes projets. Si l'un est en __cdecl et l'autre en __stdcall, ca pourra donner ce genre de comportement (sous visual studio 2005, c'est dans les propriétés avancées de la seciton C++ du projet)

Reply

Marsh Posté le 08-08-2008 à 14:52:12    

je vous prie de m'excuser, mais je n'ai pas précisé que j'étais sous UNIX... Cependant tu m'as mis un peu sur la voie et je fais des recherches en ce sens sur le net...


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 08-08-2008 à 14:52:12   

Reply

Marsh Posté le 08-08-2008 à 15:21:02    

DLL invite plus à penseer Windows, oui, j'ai fait le raccourci
 
UNIX sur x86 ?
S'il t'est possible de débugger en assembler juste avant l'appel de fonction et juste après, pour voir si les données sont bien transmises à l'endroit où on les lit ensuite, ca peut potentiellement te donner des renseignements intéressants

Reply

Marsh Posté le 08-08-2008 à 15:35:09    

en l'occurrence c'est sous SUN mais j'ai le problème sous Linux aussi. Effectivement ce sont des bibliothèques dynamiques :D

 

Je ne sais pas debugger en assembleur...


Message édité par kaloskagatos le 08-08-2008 à 15:36:17

---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Marsh Posté le 08-08-2008 à 17:00:07    

j'ai trouvé la solution, vraiment évident...

 

CalculerVariableUtilisateur dans un cas avait 10 paramètres, dans l'autre 11... Comme l'entête est déclaré en externe je suppose que la vérification n'est pas faite à la compilation et édition des liens...

 

Merci pour votre aide, je vais me cacher...

 


Message édité par kaloskagatos le 08-08-2008 à 17:00:37

---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed