SOS Marshaling char* ! [Résolu]

madkeyboard 100 Messages postés mercredi 27 avril 2011Date d'inscription 21 décembre 2012 Dernière intervention - 2 mai 2011 à 11:08 - Dernière réponse : LUDINSKI 441 Messages postés mardi 2 décembre 2003Date d'inscription 22 mai 2012 Dernière intervention
- 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 

Votre réponse

10 réponses

Meilleure réponse
LUDINSKI 441 Messages postés mardi 2 décembre 2003Date d'inscription 22 mai 2012 Dernière intervention - 3 mai 2011 à 08:54
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 );

Merci LUDINSKI 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 124 internautes ce mois-ci

Commenter la réponse de LUDINSKI
dodo7263 642 Messages postés mercredi 10 septembre 2008Date d'inscription 9 février 2017 Dernière intervention - 2 mai 2011 à 11:56
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
madkeyboard 100 Messages postés mercredi 27 avril 2011Date d'inscription 21 décembre 2012 Dernière intervention - 2 mai 2011 à 14:23
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
dodo7263 642 Messages postés mercredi 10 septembre 2008Date d'inscription 9 février 2017 Dernière intervention - 2 mai 2011 à 14:50
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
madkeyboard 100 Messages postés mercredi 27 avril 2011Date d'inscription 21 décembre 2012 Dernière intervention - 2 mai 2011 à 16:15
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
dodo7263 642 Messages postés mercredi 10 septembre 2008Date d'inscription 9 février 2017 Dernière intervention - 2 mai 2011 à 16:43
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
madkeyboard 100 Messages postés mercredi 27 avril 2011Date d'inscription 21 décembre 2012 Dernière intervention - 2 mai 2011 à 17:08
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
cs_jopop 1540 Messages postés lundi 26 mai 2003Date d'inscription 1 août 2013 Dernière intervention - 2 mai 2011 à 17:14
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
madkeyboard 100 Messages postés mercredi 27 avril 2011Date d'inscription 21 décembre 2012 Dernière intervention - 3 mai 2011 à 09:13
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
LUDINSKI 441 Messages postés mardi 2 décembre 2003Date d'inscription 22 mai 2012 Dernière intervention - 3 mai 2011 à 09:17
0
Merci
Mais de rien... bon débuggage ;)
Commenter la réponse de LUDINSKI

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.