2010-11-13 9 views
7

He escrito un dll VC++. La declaración de uno de los métodos en la DLL es como sigue:¡Pila desbalanceada!

extern "C" _declspec(dllexport) 
void startIt(int number) 
{ 
    capture = cvCaptureFromCAM(number); 
} 

Puedo utilizar este DLL en un código C# utilizando P/Invoke. Hago la declaración como:

[DllImport("Tracking.dll", EntryPoint = "startIt")] 
     public extern static void startIt(int number); 

y llamo a la función en el código como:

startIt(0); 

Ahora, cuando se encuentra esta línea, el compilador se lanzándome este error:

A call to PInvoke function 'UsingTracking!UsingTracking.Form1::startIt' has 
unbalanced the stack. This is likely because the managed PInvoke signature does 
not match the unmanaged target signature. Check that the calling convention 
and parameters of the PInvoke signature match the target unmanaged signature. 

No puedo entender por qué está lanzando este error ya que la firma en el código administrado y no administrado es la misma. Además, en mi otra máquina, el mismo código funciona perfectamente en Visual Studio. Entonces, esto me hace pensar que el error arrojado es erróneo.

Por favor ayuda.

Gracias

+0

¿Alguna de sus máquinas es x86 y la otra es x64? –

+0

No, ambos son x86. Solo uno ejecuta Win7 y otro XP – Jayesh

Respuesta

13

Cuando p/invocar una función externa, el calling convention usa de manera predeterminada __stdcall. Debido a que su función utiliza la convención __cdecl, tiene que declarar como tal:

[DllImport("Tracking.dll", EntryPoint = "startIt", 
    CallingConvention = CallingConvention.Cdecl)] 
public extern static void startIt(int number); 
+0

¡Gracias que funcionó! Sin embargo, todavía me pregunto por qué no arrojó el mismo error mientras trabajaba en Win7. – Jayesh

+0

@James, debería tener, a menos que Win7 realice plomería especial detrás de escena para cambiar a la convención de llamada correcta. –

+0

@James, ¿usó el mismo dll exacto en Win7 o lo compiló allí? – Constantin

6

Podría ser falta CallingConvention=CallingConvention.Cdecl en su atributo DllImport?

+1

Este fue mi problema al depurar este problema (después de cambiar a .NET 4). 'stdcall' es el valor predeterminado si no especifica esto! –

+0

Esto también me lo resolvió después de cambiar una solución anterior de .NET 2 a .NET 4) –

4

Constantin y Frederic Hamidi han respondido a esta pregunta correctamente en cuanto a cómo solucionar este problema. Esto puede ayudar a evitar un eventual desbordamiento de pila. He mordido esto varias veces yo mismo. Lo que realmente está en juego aquí es que .NET 4 ha habilitado un asistente de depuración administrada para compilaciones de depuración (no versión) en máquinas x86 de 32 bits (no de 64 bits) que verifica una llamada p/invocación especificada incorrectamente. Este artículo de MSDN detalla esto: http://msdn.microsoft.com/en-us/library/0htdy0k3.aspx. Stephen Cleary merece el crédito por identificar esto en esta publicación: pinvokestackimbalance -- how can I fix this or turn it off?