c# - pinvokestackimbalance: ¿cómo puedo solucionarlo o desactivarlo?
c++ visual-studio-2010 (5)
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ú.
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
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 programas 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!
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?
Para apagarlo:
- CTRL + ALT + E
- En "Asistentes de depuración gestionados" desmarque PInvokeStackImbalance.
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 compila 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
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 #)
- ve a Herramientas -> Opciones.
- En la esquina inferior izquierda del cuadro de diálogo Opciones, marque la casilla que dice "Mostrar todas las configuraciones".
- En la vista de árbol en el lado izquierdo, seleccione "Proyectos y soluciones".
- En las opciones de la derecha, marca la casilla que dice "Mostrar configuraciones avanzadas de compilación".
- Haga clic en Aceptar.
- Vaya a Build -> Configuration Manager ...
- En la columna Plataforma al lado de su proyecto, haga clic en el cuadro combinado y seleccione "".
- En la configuración "Nueva plataforma", elija "x86".
- Haga clic en Aceptar.
- 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