Allocation mémoire d'une structure passée en pointeur à une DLL C++ [Résolu]

Feanor06 34 Messages postés jeudi 18 février 2010Date d'inscription 23 juillet 2010 Dernière intervention - 25 mars 2010 à 17:06 - Dernière réponse : BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention
- 26 mars 2010 à 19:46
Bonjour !

Bon, désolé mais je dois pas être dans le bon thème, mais j'en ai pas trouvé qui collait bien (style "truc de ouf" ).

J'ai un exe en vb.net (VS 2008 Express) et une DLL en C++ (Dev-C++).

Je passe à la librairie une structure qui doit être remplie par celle-ci.
Et forcement, ça ne fonctionne pas...

Exe :

Public Structure patch
Dim xc, yc, w, h As Integer
Dim r, g, b As Double
End Structure

Public tabp(144) As patch

Result_Geom = get_geom(tabp)

DLL :

extern "C" __declspec (dllexport) __stdcall int get_geom(struct patch * tab_p)
{
tab_p[0].yc = 69; //juste pour tester une ecriture
return tab_p[10].xc; // et une lecture...
}

La j'arrive bien à lire dans la structure, mais impossible d'écrire (value toujours à 0), par contre, pas d'erreur.

J'ai essayé ça aussi, et je pense que c'est la bonne écriture, mais ça ne marche pas non plus... (tentative de lecture/écriture en mémoire protégée)

extern "C" __declspec (dllexport) __stdcall int get_geom(struct patch * tab_p[])
{
(*tab_p[0]).yc = 69;
return (*tab_p[10]).xc;
}

Je pense que c'est un problème d'allocation mémoire, qu'il faudrait faire dans l'exe après la déclaration de la structure mais tout ce que j'ai essayé ne fonctionne pas en raison du type de data de celle-ci (pas un IntPtr, non Blittable...).

J'ai plus d'idée...

Merci à vous !!!
Afficher la suite 

Votre réponse

12 réponses

Meilleure réponse
lesdis 401 Messages postés mercredi 19 avril 2006Date d'inscription 6 juin 2011 Dernière intervention - 26 mars 2010 à 10:17
3
Merci
Bonjour,

Effectivement, la structure n'était pas modifier.
Voici une solution qui fonctionne :
- On passe la variable par référence
- Le pointeur d'un tableau correspond à sa première occurrence.

Par contre, il y a un truc qui m'embête, c'est que si l'on dépasse les limites du tableau dans la dll, je ne reçois aucun message d'erreur


<Runtime.InteropServices.DllImport("maDLL.dll")> _
Private Shared Function Ouvrir(ByRef tab_patch() As patch) As Integer
End Function

Public tab_patch(144) As patch

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Ouvrir(tab_patch(0))
  MessageBox.Show(tab_patch(10).xc, "Test", MessageBoxButtons.OK, MessageBoxIcon.None)
End Sub



struct patch {
int xc, yc, w, h;
double r, g, b;
};

int Ouvrir(struct patch * tab_p)
{
tab_p[0].yc = 69;
tab_p[10].xc=15;
return 1; 
}



Bonne Prog

Merci lesdis 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de lesdis
Feanor06 34 Messages postés jeudi 18 février 2010Date d'inscription 23 juillet 2010 Dernière intervention - 25 mars 2010 à 17:08
0
Merci
Je précise que je déclare la structure de la même manière que dans l'exe en vb dans le .h de la DLL :

struct patch {
int xc, yc, w, h;
double r, g, b;
};

PLEASE HELP
Commenter la réponse de Feanor06
lesdis 401 Messages postés mercredi 19 avril 2006Date d'inscription 6 juin 2011 Dernière intervention - 25 mars 2010 à 17:38
0
Merci
Bonjour,

Je viens de faire le test et tout fonctionne pour ma part,

j'ai repris le code vb sans y toucher :
 
<Runtime.InteropServices.DllImport("maDLL.dll")> _
Private Shared Function Ouvrir(ByVal toto() As patch) As Integer
End Function

Public toto(144) As patch

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  MsgBox(Ouvrir(toto))
End Sub


Et pour le code C(c'était plus rapide pour moi)
struct patch {
int xc, yc, w, h;
double r, g, b;
};

int Ouvrir(struct patch * tab_p)
{
tab_p[0].yc = 69; //juste pour tester une ecriture
tab_p[10].xc=15;
return tab_p[10].xc; // et une lecture... 
}



La boite de dialogue me ressort bien 15.
A voir si c'est un soucis de déclaration de fonction


Bonne Prog
Commenter la réponse de lesdis
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 25 mars 2010 à 17:52
0
Merci
int Ouvrir(struct patch * tab_p)
{
tab_p[0].yc = 69; //juste pour tester une ecriture
tab_p[10].xc=15;
return tab_p[10].xc; // et une lecture...
}

Juste pour la précision:
un compilo C correct ne fait aucune lecture ici, la valeur 15 aura été mise dans EAX, ensuite EAX mis dans tab_p[10].xc et illico c'est "RET 4" pour retour chez l'appelant.

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
Feanor06 34 Messages postés jeudi 18 février 2010Date d'inscription 23 juillet 2010 Dernière intervention - 25 mars 2010 à 18:01
0
Merci
Et bien tout d'abord merci beaucoup à vous deux !

Ensuite, BruNews, pour bien comprendre, tu veux dire qu'en fait le compilo se souvient de l'affectation qu'il a fait juste au dessus et ne "s'embête" pas à lire dans la structure en affichant 15 ?

Ça expliquerai pourquoi ça fonctionne chez lesdis ? Qu'il n'aurait pas vraiment écrit dans la structure ?
Je cherche juste à comprendre, je ne mets pas en doute ce que tu dis lesdis.
Commenter la réponse de Feanor06
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 25 mars 2010 à 18:40
0
Merci
NON, on écrit bien dans la structure mais par le biais de EAX préalablement affecté, ainsi valeur de retour et affectation dans la structure ne sont codés (ASM par compilo C) qu'1 seule fois.
Un compilo C est un monstre d'optimisation.

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
Feanor06 34 Messages postés jeudi 18 février 2010Date d'inscription 23 juillet 2010 Dernière intervention - 25 mars 2010 à 19:58
0
Merci
Ah ok, oui, je comprends.
Merci de la précision !

lesdis, je veux pas abuser mais pour être certain que ça fonctionne dans les 2 sens, peux-tu essayer, avec ton bout de code, de lire le 69 écrit dans yc sous vb, parce que le problème que j'ai, avec ces déclarations, c'est qu'en vb je vois que des 0 après la fonction.

Par contre avec la 2ème solution((*tab_p[0]).yc = 69;), j'ai une alerte de lecture/écriture en mémoire protégée.

Merci beaucoup et bonne soirée à tous !
Commenter la réponse de Feanor06
lesdis 401 Messages postés mercredi 19 avril 2006Date d'inscription 6 juin 2011 Dernière intervention - 25 mars 2010 à 20:16
0
Merci
N'ayant pas VS chez moi, je verrais ca demain matin au boulot.


Bonne Prog
Commenter la réponse de lesdis
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscription 28 août 2015 Dernière intervention - 25 mars 2010 à 20:22
0
Merci
Salut
Info à vérifier en .Net :
Sous VB6,
Dim xc, yc, w, h As Integer 
ne signifie pas que chaque élément sera dimensionné en Integer.
Seul h le sera, les précédent seront des Variant
-->
Dim xc As Integer, yc As Integer, w As Integer, h As Integer 

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Commenter la réponse de cs_Jack
Feanor06 34 Messages postés jeudi 18 février 2010Date d'inscription 23 juillet 2010 Dernière intervention - 26 mars 2010 à 09:37
0
Merci
Merci de la proposition Jack mais en vb.net, le typage multiple fonctionne bien.

Et je confirme lesdis, ce que tu proposes fonctionne mais moi, je n'ai rien dans la structure coté VB, je pense que c'est pareil pour toi. Et je ne comprends toujours pas pourquoi...
Commenter la réponse de Feanor06
Feanor06 34 Messages postés jeudi 18 février 2010Date d'inscription 23 juillet 2010 Dernière intervention - 26 mars 2010 à 10:45
0
Merci
Ok merci, c'est parfait !!!

Par contre (ça pourra servir à quelqu'un d'autre...), dans la déclaration de la fonction de la DLL sous VB, je pense qu'il faut enlever les parenthèses puisque tu ne passes qu'un élément :
Private Shared Function Ouvrir(ByRef tab_patch As patch)

Et bien en tous cas merci beaucoup pour ton aide !!!!

Bonne journée et bon week-end à tous !

PS : si quelqu'un peut un jour m'expliquer pourquoi ça ne fonctionnait pas avant et le coup du message d'erreur que soulève lesdis, je suis preneur.
Commenter la réponse de Feanor06
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 26 mars 2010 à 19:46
0
Merci
On n'a pas de message d'erreur tant qu'on écrit sur des octets de mémoire "writable".
Une DLL prenant un tableau à remplir doit toujours avoir un param 'count'. Il faut prendre exemple sur l'API Windows, c'est toujours ainsi.

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.