pinvokestackimbalance: ¿cómo puedo solucionarlo o desactivarlo?

Acabo de cambiar a vs2010 desde vs2008. Exactamente la misma solución, excepto que ahora cada llamada a un dll de C ++ genera una excepción ‘pinvokestackimbalance’.

Esta excepción no se disparó en 2008. Tengo acceso completo a la dll de C ++ y a la aplicación de llamada. No parece haber ningún problema con el pinvoke, pero este problema está haciendo que la depuración de otros problemas sea imposible; el IDE se detiene constantemente para contarme sobre estas cosas.

Por ejemplo, aquí está la firma C #:

[DllImport("ImageOperations.dll")] static extern void FasterFunction( [MarshalAs(UnmanagedType.LPArray)]ushort[] inImage, //IntPtr inImage, [MarshalAs(UnmanagedType.LPArray)]byte[] outImage, //IntPtr outImage, int inTotalSize, int inWindow, int inLevel); 

Esto es lo que parece en el lado de C ++:

 #ifdef OPERATIONS_EXPORTS #define OPERATIONS_API __declspec(dllexport) #else #define OPERATIONS_API __declspec(dllimport) #endif extern "C" { OPERATIONS_API void __cdecl FasterFunction(unsigned short* inArray, unsigned char* outRemappedImage, int inTotalSize, int inWindow, int inLevel); } 

¿Cuál es la diferencia entre vs2010 y vs2008 que provocaría que se lanzaran estas excepciones? ¿Debería agregar un conjunto diferente de parámetros a la directiva DllImport?

Primero, entienda que el código está mal (y siempre lo ha sido). El “pInvokeStackImbalance” no es una excepción per se, sino un asistente de depuración administrado. Estaba desactivado por defecto en VS2008, pero mucha gente no lo activó, por lo que está activado por defecto en VS2010. El MDA no se ejecuta en modo Release, por lo que no se activará si comstack para su lanzamiento.

En su caso, la convención de llamadas es incorrecta. DllImport predeterminada en CallingConvention.WinApi , que es idéntico a CallingConvention.StdCall para el código de escritorio x86. Debería ser CallingConvention.Cdecl .

Esto se puede hacer editando la línea [DllImport("ImageOperations.dll")] para que sea:

 [DllImport("ImageOperations.dll", CallingConvention = CallingConvention.Cdecl)] 

Para obtener más información, consulte esta referencia de MSDN

Para apagarlo:

  1. CTRL + ALT + E
  2. En “Asistentes de depuración gestionados” desmarque PInvokeStackImbalance.

Es mejor resolver este problema, no es muy difícil, aquí estoy mencionando algunos de los métodos, puede ser igual que algunos de mis amigos mencionados anteriormente. Estoy trabajando con PCSC, una aplicación de tarjeta inteligente que gasto alrededor de una semana, me cabreo, muchos cambios finalmente obtuvieron las soluciones.

Para mí, su trabajo con PInvoke Extension, que instalé para VS2010, puede descargarlo aquí http://www.red-gate.com/products/dotnet-development/pinvoke/

Descárguelo e instálelo, cierre Visual Studio y vuelva a abrir para encontrar la extensión en la barra de menú. enter image description here

Si el error se debe a que la firma no coincide, simplemente haga clic en PInvoke.net> Insertar firmas de invocación

La nueva ventana aparecerá como abajo enter image description here

Ingrese el nombre de la dll y haga clic en buscar. Puede ver todas las funciones de esa dll en la ventana de resultados de búsqueda. Haga clic en la función para obtener una firma para esa función en particular.

Use esa firma y debe modificar sus progtwigs según esa Firma, principalmente el tipo de datos.

Esto resuelve mi problema, es posible que tenga un problema diferente, como llamar a Convention o atributos adicionales que deba especificar al importar dll.

Happy Coding ¡Esté bien!

También tengo este problema cuando uso VS2010. Qué es: Visual Studio tiene por defecto el código de 64 bits para ‘cualquier CPU’. Los punteros a las variables (por ejemplo, cadenas de caracteres) ahora se convierten en 64 bits al llamar a sus Dlls externos, mientras que todos sus Dlls confiables y confiables usan punteros de 32 bits.

No supongas que hay algo mal con tus Dlls, no hay.

Cambie su configuración VS para generar código X86 como este (versiones Express de C #)

  1. ve a Herramientas -> Opciones.
  2. En la esquina inferior izquierda del cuadro de diálogo Opciones, marque la casilla que dice “Mostrar todas las configuraciones”.
  3. En la vista de árbol en el lado izquierdo, seleccione “Proyectos y soluciones”.
  4. En las opciones de la derecha, marca la casilla que dice “Mostrar configuraciones avanzadas de comstackción”.
  5. Haga clic en Aceptar.
  6. Vaya a Build -> Configuration Manager …
  7. En la columna Plataforma al lado de su proyecto, haga clic en el cuadro combinado y seleccione “”.
  8. En la configuración “Nueva plataforma”, elija “x86”.
  9. Haga clic en Aceptar.
  10. Haga clic en Cerrar.

También me doy cuenta de que, aunque las computadoras se han duplicado en potencia cada 12 meses, mi computadora actual con 1 giga de RAM, parece no ser más rápida que mi primera 486 con 4 Meg. No se preocupe por usar código de 64 bits, no será más rápido o mejor porque está construido sobre una enorme torre de hinchamiento orientada a objetos.

Traté de llamar a dll con el CallingConvention es ThisCall y funcionó para mí. Aquí está mi código trabajando con BLOB MS Sql Server.

 [DllImport("sqlncli11.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.ThisCall)] private static extern SafeFileHandle OpenSqlFilestream( string FilestreamPath, UInt32 DesiredAccess, UInt32 OpenOptions, byte[] FilestreamTransactionContext, UInt32 FilestreamTransactionContextLength, Int64 AllocationSize); 

Más información en: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx