garcimor59
Messages postés66Date d'inscriptionmardi 18 juillet 2006StatutMembreDernière intervention 6 mars 2008
-
5 mars 2008 à 17:59
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 2012
-
7 mars 2008 à 03:57
Bonjour,
Voilà j'utilise une DLL faite en C (pas sur) dans du code C#, j'ai donc suivit la méthode indiquée dans les differents posts du forum.
Cela fonctionne correctement pour 2 fonctions de la DLL, mais pour une ça ne fonctionne pas.
Voilà le code que j'ai :
[DllImport("opdes.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern byte[] OF_MAC
(
byte[] MESSAGE
// return parameter is a list of 8 bytes;
//-- MESSAGE : input parameter list of 200_000 bytes
);
Ma fonction C# qui appelle cette fonction :
public static byte[] CBC_MAC(byte[] argMsg, string argKey)
{
try
{
byte[] KTRANS = HexToByte(argKey);
OP_INPUT_3KEYS(KTRANS); //Une des fonctions de la dll qui fonctionne trés bien
byte[] test = new byte[200000];
byte[] CYPHER = new byte[8];
byte[] CYPHER = OF_MAC(test);
return CYPHER;
}
catch { return null; }
}
Et voilà l'erreur que je récupere dans mon catch :
Impossible de marshaler 'return value' : Combinaison de types managés/non managés non valide.
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 5 mars 2008 à 19:14
Salut, c'est toujours un problème ce genre de fonction qui renvoie un tableau.. la valeur de retour ne peut pas être un tableau, ça doit être un IntPtr, ( dans ton cas on pourrait même s'amuser à marshaller en Uint64 soit 8 bytes ). Le problème c'est que le tableau a été alloué dans le code non-managé, on ne peut plus libérer la mémoire dans le code managé, à moins de disposer d'une fonction genre FREE_OF_MAC( byte[ ] result ) ou avoir utiliser CoTaskMemAlloc du coté non-managé. Tu auras donc peut être ( ou peut être pas ) un mémory leak de 8 bytes à chaque appel de cette fonction. :/
garcimor59
Messages postés66Date d'inscriptionmardi 18 juillet 2006StatutMembreDernière intervention 6 mars 2008 6 mars 2008 à 11:11
Re,
Bon j'ai essayé avec le code suivant :
[DllImport("opdes.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern IntPtr OF_MAC
(
byte[] MESSAGE
// return parameter is a list of 8 bytes;
//-- MESSAGE : input parameter list of 200_000 bytes the first byte is the MSB of length
//-- the fourth byte is LSB of the length. (first byte always = 0)
//-- Length is the message length (4 bytes of length not include)
//-- Length is (0 .. 196_000)
);
public static byte[] CBC_MAC(byte[] argMsg, string argKey)
{
try
{
byte[] KTRANS = HexToByte(argKey);
OP_INPUT_3KEYS(KTRANS);
byte[] test = new byte[200000];
byte[] CYPHER = new byte[8];
IntPtr p = OF_MAC(test);
return CYPHER;
}
catch { return null; }
}
Et j'ai l'erreur suivante :
Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée.
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 6 mars 2008 à 13:06
En fait soit ta fonction renvoie une référence ( un pointeur ) dans ce cas il faut utiliser un IntPtr puis la méthode Marshal.Copy ( ou le code unsafe ) pour transformer le IntPtr en tableau de bytes soit ta fonction renvoie un "type valeur" et dans ce cas il faut utiliser un Int64 puis la méthode BitConverter.GetBytes.
Vous n’avez pas trouvé la réponse que vous recherchez ?
garcimor59
Messages postés66Date d'inscriptionmardi 18 juillet 2006StatutMembreDernière intervention 6 mars 2008 6 mars 2008 à 14:04
Je suis pas sur d'avoir compris ce que tu as dis.
En gros, tu m'expliques comment récuperer un tableau de byte selon que la fonction retourne un IntPtr ou un Int64 (si j'ai bien compris :-) )
Bon si c'est ça, je suis ok et je vois comment faire.
Mon probleme c'est que je n'arrive à rien récuperer lors de l'appel de la fonction.
Que ça soit avec un IntPtr ou un Int64 j'ai toujours la meme erreur dans mon catch :
Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée.
Voilà, je ne sais plus quoi tester... a votre bon coeur m'sieur dame...
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 7 mars 2008 à 03:57
Dans Visual Studio clique droit sur ton projet -> propriétés -> Générer -> Autoriser le code unsafe. Ou avec le compilo en ligne de commande option "-unsafe".
Vire le "CharSet.Auto" qui joue peut être des tours.
Autant l'erreur "Impossible de marshaler 'return value' .. " est normale, par contre la seconde "Tentative de lecture ou d'écriture de mémoire protégée .. " là je ne vois pas :/