2010-12-09 52 views
5

J'ai une DLL C++ qui a une fonction dans ce que j'essaye d'appeler à partir d'une application C#.Problème avec C# <-> C++ DLLImport "Tentative de lecture ou d'écriture de la mémoire protégée."

Voici le code dans le fichier d'en-tête C de

extern "C" _declspec(dllexport) int LabelStoringSSDsim(int devNum, UCHAR serial[40], UCHAR wwn[40], 
       UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode); 

Voici le code dans le fichier source C++

int LabelStoringSSDsim(int devNum, UCHAR serialLbl[40], UCHAR wwnLbl[40], 
       UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode) 

{

string strConfigID="12111";          //5 bytes 
string strFrmRev="1.25....";         //8 bytes 
string strDevName="ABC-123................................."; //40 bytes 

for (int i=0;i<5;i++) 
    ConfigID[i] = strConfigID[i]; 

for (int i=0;i<8;i++) 
    FrmRev[i] = strFrmRev[i]; 

for (int i=0;i<40;i++) 
    DevName[i] = strDevName[i]; 
return eCode; 

}

est ici le C# pertinent Donc, quand j'arrive au dernier bit de code, j'obtiens le message "Tentative de lecture ou d'écriture de la mémoire protégée." Ceci est souvent une indication qu'une autre mémoire est corrompue. » Erreur.

Je n'ai aucune expérience préalable dans l'importation DLL est comme ça et je l'ai fait beaucoup de recherche, mais ne peut pas sembler trouver une solution au problème.

J'ai essayé de repartir de zéro avec une simple fonction retournant un nombre entier, et cela a fonctionné.J'ai ajouté un int pour que je passe à la fonction et cela a fonctionné.Puis j'ai ajouté un tableau d'octets pour que je passe Ensuite, j'ai essayé de transformer ce tableau d'octets en une référence et il a échoué, donc je suppose que je reçois les données de façon incorrecte

Toute aide est grandement appréciée

Répondre

5

Essayez de remplacer [In] par [In, Out]. Je ne suis pas sûr d'utiliser les mots-clés ref et [In, Out] ensemble sur un seul argument. (Edit: Hans Passant a une bonne explication des différences entre les deux dans son commentaire ci-dessous.)

Voir this MSDN article pour plus d'informations, en particulier le passage, "Par défaut, les types de référence (classes, tableaux, chaînes et interfaces Les valeurs passées par valeur sont marshalées en tant que paramètres In pour des raisons de performances.Vous ne voyez pas les modifications apportées à ces types sauf si vous appliquez InAttribute et OutAttribute (ou simplement OutAttribute) au paramètre method. "

+0

qui produit l'erreur suivante: L'exception de type 'System.ExecutionEngineException' a été levée. – Chris

+0

@Chris, je pense avoir eu une erreur de syntaxe. Essayez ma nouvelle version améliorée ci-dessus. –

+0

Désolé, toujours la même chose: X - L'erreur se produit à ce dernier bit de code à la place de l'erreur précédente. – Chris

1

J'ai commencé à recevoir périodiquement cette exception durring natif interop après la mise à niveau vers Windows 7. Le code avait toujours fonctionné sous XP et avait moins de problèmes sur Windows 7 si j'avais exécuté mon application en mode de compatibilité XP. Après quelques recherches et expérimentations, j'ai découvert que la raison pour laquelle je recevais cette exception était liée à l'appel d'une fonction native qui renvoyait une chaîne (WCHAR *).

Je ne crois pas qu'il y ait actuellement un correctif pour cela car même la mise à jour vers .Net 3.5 n'a pas résolu le problème ... Cependant, j'ai trouvé le travail suivant.

Exemple de ce qui fonctionne sur XP, mais ne fonctionne pas sur Windows 7:

[DllImport("NativeBin.dll")] 
public static extern String GetWCharStr(); 

Exemple de ce qui fonctionne pour moi sur Windows 7 et XP:

[DllImport("NativeBin.dll")] 
private static extern IntPtr GetWCharStr(); 
public static String GetString() 
{ 
    return Marshal.PtrToStringUni(GetWCharStr()); 
}