2010-12-09 43 views
5

Tengo un dll C++ que tiene una función dentro. Estoy intentando llamar desde una aplicación C#.Problema con C# <-> C++ DLLImport "Intentó leer o escribir en la memoria protegida".

Aquí está el código en el archivo de cabecera de C++

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); 

Aquí está el código en el archivo C++ fuente

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; 

}

Aquí está la C# pertinente código

 [DllImport("LabelStoring.dll")] 
    static extern int LabelStoringSSDsim(
     int devNum, 
     byte[] strserial, 
     byte[] strwwn, 
     [In] ref byte[] ConfigID, 
     [In] ref byte[] FrmRev, 
     [In] ref byte[] DevName, 
     int eCode); 


int errNum = LabelStoringSSDsim(devNum, bserial, bwwn, ref ConfigID, ref FrmRev, ref DevName, 123123); 

De modo que cuando llego al último bit de código, aparece el mensaje "Intenté leer o escribir en la memoria protegida". Esto es a menudo una indicación de que otra memoria está dañada." Error.

que no tienen experiencia previa en la importación de DLL de esta manera y he hecho un montón de búsqueda, pero parece que no puede encontrar una solución al problema.

Intenté empezar desde cero con una función simple devolviendo un entero, y funcionó. Luego agregué un int para que pasara a la función y aún así funcionó. Luego agregué una matriz de bytes para pasar, lo que funcionó Luego intenté convertir ese conjunto de bytes en una referencia y falló. Así que mi suposición es que estoy obteniendo los datos incorrectamente.

Cualquier ayuda es muy apreciada.

Respuesta

5

Intente cambiar [In] por [In, Out]. Tampoco estoy seguro sobre el uso de las palabras clave ref y [In, Out] juntas en un solo argumento. (Editar: Hans Passant tiene una buena explicación de las diferencias entre los dos en su comentario a continuación.)

Consulte this MSDN article para obtener más información, especialmente el pasaje, "De forma predeterminada, los tipos de referencia (clases, matrices, cadenas e interfaces)) los valores pasados ​​se clasifican como parámetros In por motivos de rendimiento. No verá cambios en estos tipos a menos que aplique InAttribute y OutAttribute (o solo OutAttribute) al parámetro del método ".

+0

que produce el error siguiente: Se lanzó la excepción de tipo 'System.ExecutionEngineException'. – Chris

+0

@Chris, creo que tuve un error de sintaxis. Prueba mi nueva versión mejorada arriba. –

+0

Lo sentimos, sigue siendo lo mismo: X - El error se produce en ese último bit de código en lugar del error anterior. – Chris

1

Empecé a recibir esta excepción durante la interoperabilidad nativa periódicamente después de actualizar a Windows 7. El código siempre había funcionado en XP y tiene menos problemas en Win 7 si ejecuté mi aplicación en el modo de compatibilidad de XP.

Después de un poco de investigación y experimentación, descubrí que la razón por la que recibía esta excepción tenía que ver con llamar a una función nativa que devolvía una cadena (WCHAR *).

No creo que haya una solución para esto, ya que incluso la actualización a .Net 3.5 no solucionó el problema ... Sin embargo, encontré el siguiente trabajo.

Ejemplo de lo que funciona en XP, pero no funciona en Windows 7:

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

Ejemplo de lo que funciona para mí en Windows 7 y XP:

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