SOS Marshaling char* !

Résolu
madkeyboard Messages postés 100 Date d'inscription mercredi 27 avril 2011 Statut Membre Dernière intervention 21 décembre 2012 - 2 mai 2011 à 11:08
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

10 réponses

LUDINSKI Messages postés 441 Date d'inscription mardi 2 décembre 2003 Statut Membre Dernière intervention 22 mai 2012 8
3 mai 2011 à 08:54
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 );
3
dodo7263 Messages postés 614 Date d'inscription mercredi 10 septembre 2008 Statut Membre Dernière intervention 9 février 2017 6
2 mai 2011 à 11:56
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
0
madkeyboard Messages postés 100 Date d'inscription mercredi 27 avril 2011 Statut Membre Dernière intervention 21 décembre 2012 1
2 mai 2011 à 14:23
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 ?
0
dodo7263 Messages postés 614 Date d'inscription mercredi 10 septembre 2008 Statut Membre Dernière intervention 9 février 2017 6
2 mai 2011 à 14:50
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
madkeyboard Messages postés 100 Date d'inscription mercredi 27 avril 2011 Statut Membre Dernière intervention 21 décembre 2012 1
2 mai 2011 à 16:15
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 !
0
dodo7263 Messages postés 614 Date d'inscription mercredi 10 septembre 2008 Statut Membre Dernière intervention 9 février 2017 6
2 mai 2011 à 16:43
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
0
madkeyboard Messages postés 100 Date d'inscription mercredi 27 avril 2011 Statut Membre Dernière intervention 21 décembre 2012 1
2 mai 2011 à 17:08
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 ?
0
cs_jopop Messages postés 1540 Date d'inscription lundi 26 mai 2003 Statut Membre Dernière intervention 1 août 2013 12
2 mai 2011 à 17:14
Salut,

dans ton import, avec char* (unsafe) ou char[] ça ne fonctionne pas ? Sinon t'as tenté ta chance avec un IntPtr ?
0
madkeyboard Messages postés 100 Date d'inscription mercredi 27 avril 2011 Statut Membre Dernière intervention 21 décembre 2012 1
3 mai 2011 à 09:13
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
0
LUDINSKI Messages postés 441 Date d'inscription mardi 2 décembre 2003 Statut Membre Dernière intervention 22 mai 2012 8
3 mai 2011 à 09:17
Mais de rien... bon débuggage ;)
0
Rejoignez-nous