SOS Marshaling char* ! [Résolu]

Messages postés
100
Date d'inscription
mercredi 27 avril 2011
Statut
Membre
Dernière intervention
21 décembre 2012
- - Dernière réponse : LUDINSKI
Messages postés
441
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
22 mai 2012
- 3 mai 2011 à 09:17
Bonjour !

Voila une question qui suit mon dernier post :
http://www.csharpfr.com/forum/sujet-PROBLEME-UTILISATION-DLL-CSHARP_1515979.aspx

J'ai enfin pu utiliser des dll non managées.

Maintenant, je doit utiliser la dll d'un collègue, et principalement la méthode dont la définition est :

char* CIntNum::Execute(char* Command)
{

CString strRetour;
CString m_Command;
m_Command=Command;
BYTE ucTmp;

if(m_Command=="CONNECT")
{		
if(Connect())
{
strRetour="CONNECTION_OK";

}
else
{
strRetour="ERREUR";
}
}

else if(m_Command=="INTENSITY+VBROCHE")
{

strRetour=GetIntensity();
}

else if(m_Command=="GET_VAL_MAX_T")
{

strRetour=GetValMaxT();
}

else if(m_Command=="TEMP_OK")
{
ucTmp=1;

if(WriteLadderVar(m_sPort,V0,0x20,1,&ucTmp)==0)
{

strRetour="TEMP_OK";
}
else
{
strRetour="ERREUR_TEMP";
}

}
else if(m_Command=="TEMP_BAD")
{
ucTmp=0;

if(WriteLadderVar(m_sPort,V0,0x20,1,&ucTmp)==0)
{
strRetour="TEMP_BAD";
}
else
{
strRetour="ERREUR_TEMP";
}

}
else if(m_Command=="BLOCAGE1")
{
short sVarBloc1=1;
if (WriteLadderVar(m_sPort,M0,0x5000,1,&sVarBloc1)==0)
{
CString strTampon="1";
WritePrivateProfileString("Configuration CRENO","NIV_BLOC",strTampon,"initValCreno.ini");
strRetour="OK";
}
else { strRetour="ERROR";}

}
else if(m_Command=="BLOCAGE2")
{
short sVarBloc2=1;
if (WriteLadderVar(m_sPort,M1,0x5000,1,&sVarBloc2)==0)
{
strRetour="OK";
}
else { strRetour="ERROR";}
}
else if(m_Command=="BLOCAGE0")
{
short sVarBloc1=0;
if (WriteLadderVar(m_sPort,M0,0x5000,1,&sVarBloc1)==0)
{
strRetour="OK";
}
else { strRetour="ERROR";}
if (WriteLadderVar(m_sPort,M1,0x5000,1,&sVarBloc1)==0)
{
strRetour="OK";
}
else { strRetour="ERROR";}

}


else if(m_Command=="CLOSE")
{

Close();
}

return strRetour.GetBuffer(0);
}

Je travail donc en c#, j'ai donc fait l'import de la dll contenant cette méthode, en utilisant bien une 20aine de déclaration différentes (parce que j'ai toujours un bug), en suivant les tutos et les topics de forum sur la question :

[DllImport("InterpretTempIntensity.dll")]
static extern string Execute(string Command);

//ou
[DllImport("InterpretTempIntensity.dll")]
static extern IntPtr Execute(StringBuilder Command);

//ou
[DllImport("InterpretTempIntensity.dll")]
static extern byte[] Execute(byte[] Command);

//ou
[DllImport("InterpretTempIntensity.dll")]
unsafe static extern byte*[] Execute(byte*[] Command);

//ou
[DllImport("InterpretTempIntensity.dll")]
unsafe static extern char* Execute(char* Command);

... et j'en passe et des meilleurs...

Je ne vous met pas l'appel de la fonction, je déclare bêtement 2 variables pour les 2 paramètres (entrée et retour). J'ai aussi fait une infinité de test avec des Marshal.StringToHGlobalAnsi et autres...

Dans tous les cas, lors de l'appel de la fonction (pendant l'excecution), j'obtient systématiquement une exception. Elle varie un peu selon les cas :

J'ai déja eu des exceptions qui m'expliquait qu'une conversion managé/non managé était non valide (j'ai plus la formulation exacte)...

Mais la plus récurrente est :
"Un appel à la fonction PInvoke 'WindowsFormsTestComNUM1060!WindowsFormsTestComNUM1060.ComNum::Execute' a déséquilibré la pile. Cela peut se produire, car la signature PInvoke managée ne correspond pas à la signature cible non managée. Vérifiez que la convention d'appel et les paramètres de la signature PInvoke correspondent à la signature non managée cible."

Please Help Me !!!

mad keyboard
Afficher la suite 

10 réponses

Meilleure réponse
Messages postés
441
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
22 mai 2012
6
3
Merci
Salut,

Il faut indiquer QUI du programme C# ou de la DLL va nettoyer la pile des appels... j'avait poster un exemple ici !

Essayes avec le code suivant :
[DllImport( "InterpretTempIntensity.dll", EntryPoint = "Execute", CallingConvention = CallingConvention.Cdecl ) ]
public static extern string Execute( string command );

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 200 internautes nous ont dit merci ce mois-ci

Commenter la réponse de LUDINSKI
Messages postés
642
Date d'inscription
mercredi 10 septembre 2008
Statut
Membre
Dernière intervention
9 février 2017
4
0
Merci
Salut,

Voici peut-être pour toi un élément de réponse. Regarde ici.

Ce n'est pas la solution mais ça peut te mettre au moins sur la piste...

@pluche


[b]"Chez ceux qui semblent très vertueux se cachent en général la vanité, l'orgueil, l'intolérance".

P.Coehlo (Maktub 2004)/b
Commenter la réponse de dodo7263
Messages postés
100
Date d'inscription
mercredi 27 avril 2011
Statut
Membre
Dernière intervention
21 décembre 2012
0
Merci
Merci, mais comme tu dit, y'a pas la solution à mon problème !

Dans ton lien, c'est codé en basic, et non en C# !
Et comme moi, il avait un problème avec les types de variable, mais cela concernait les entiers, moi cela concerne les char* :s

Une autre idée ?
Commenter la réponse de madkeyboard
Messages postés
642
Date d'inscription
mercredi 10 septembre 2008
Statut
Membre
Dernière intervention
9 février 2017
4
0
Merci
Oui je sais mais ça peut être le fond de ton problème.
Ne serait ce pas un problème de type en le char* de ta dll et les types que tu utilises pour déclarer ta fonction en c# ?

Après faut adapter pour ton problème spécifique.

@pluche


[b]"Chez ceux qui semblent très vertueux se cachent en général la vanité, l'orgueil, l'intolérance".

P.Coehlo (Maktub 2004)/b
Commenter la réponse de dodo7263
Messages postés
100
Date d'inscription
mercredi 27 avril 2011
Statut
Membre
Dernière intervention
21 décembre 2012
0
Merci
Bien que c'est ça mon problème !
Je ne sais pas comment adapter les variables char* de la dll native dans mon code c# = "marshaling" ! C'est le titre même de mon topic...

Donc dans ce cas, je repose ma question plus simplement : je fait quoi comme prototype de la méthode que je veux utiliser lors de mon import dans le c# ? ou plus concrètement, j'utilise quels types de variable en entrée et en retour ? (cf mon premier msg : j'ai déja fait 10000 tests)

Help !
Commenter la réponse de madkeyboard
Messages postés
642
Date d'inscription
mercredi 10 septembre 2008
Statut
Membre
Dernière intervention
9 février 2017
4
0
Merci
Re,

Essais ceci dans la déclaration :
[DllImport("your.dll", CharSet = CharSet.Ansi)]



[b]"Chez ceux qui semblent très vertueux se cachent en général la vanité, l'orgueil, l'intolérance".

P.Coehlo (Maktub 2004)/b
Commenter la réponse de dodo7263
Messages postés
100
Date d'inscription
mercredi 27 avril 2011
Statut
Membre
Dernière intervention
21 décembre 2012
0
Merci
Ok, mais je mais quoi pour ma fonction ???

J'ai essayé comme ça :

[DllImport("InterpretTempIntensity.dll", CharSet = CharSet.Ansi)]
static extern string Execute(string Command);

Bien entendu, même erreur...

Je supposeque les string c'est pas une solution !
J'utilise quoi dans ce cas ?
Commenter la réponse de madkeyboard
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
11
0
Merci
Salut,

dans ton import, avec char* (unsafe) ou char[] ça ne fonctionne pas ? Sinon t'as tenté ta chance avec un IntPtr ?
Commenter la réponse de cs_jopop
Messages postés
100
Date d'inscription
mercredi 27 avril 2011
Statut
Membre
Dernière intervention
21 décembre 2012
0
Merci
Fabuleux !
ça marche nickel ^^

Je te remercie pour ton aide précieuse Ludinski ! J'avais pas vu ton exemple de code, mais je vais l'étudier en détail, pour éviter de revenir avec des problèmes déja résolus

Il me reste plus qu'a débugger mon programme...

Aller, merci pour tout et à une prochaine !

mad keyboard
Commenter la réponse de madkeyboard
Messages postés
441
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
22 mai 2012
6
0
Merci
Mais de rien... bon débuggage ;)
Commenter la réponse de LUDINSKI