2010-11-13 3 views
7

Ho scritto una DLL VC++. La dichiarazione di uno dei metodi nel dll è la seguente:Stack sbilanciato!

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

Io uso questa DLL in un codice C# utilizzando P/Invoke. Faccio la dichiarazione come:

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

e chiamo la funzione nel codice come:

startIt(0); 

Ora, quando si incontra questa linea, il compilatore mi gettando questo errore:

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. 

Non riesco a capire perché genera questo errore poiché la firma nel codice gestito e non gestito è la stessa. Inoltre, nella mia altra macchina, lo stesso codice funziona perfettamente nello studio visivo. Quindi, questo mi fa pensare che l'errore che si genera sia sbagliato.

Per favore aiuto.

Grazie

+0

Una delle macchine x86 e l'altra x64? –

+0

No, entrambi sono x86. Solo quello esegue Win7 e altri XP – Jayesh

risposta

13

Quando si richiama una funzione esterna, calling convention viene utilizzato per default su __stdcall. Dal momento che la funzione utilizza la convenzione __cdecl, è necessario dichiarare come tale:

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

Grazie! Tuttavia, mi chiedo ancora perché non ha generato lo stesso errore mentre si lavora su Win7! – Jayesh

+0

@James, dovrebbe avere, a meno che Win7 non esegua uno speciale impianto idraulico dietro le quinte per passare alla convenzione di chiamata corretta. –

+0

@James, hai usato la stessa identica DLL su Win7 o l'hai ricompilata lì? – Constantin

6

Potrebbe mancare CallingConvention=CallingConvention.Cdecl nella tua attributo DllImport?

+1

Questo era il mio problema durante il debug di questo problema (dopo il passaggio a .NET 4). 'stdcall' è il valore predefinito se non lo specifichi! –

+0

Questo lo ha risolto anche per me dopo aver passato una vecchia soluzione da .NET 2 a .NET 4) –

4

Constantin e Frederic Hamidi hanno risposto a questa domanda in modo corretto su come risolvere questo problema. Questo può aiutare a evitare un eventuale overflow dello stack. Ho morso più volte da me stesso. In questo caso, .NET 4 ha abilitato un assistente di debug gestito per le build di debug (non di rilascio) su macchine x86 a 32 bit (non a 64 bit) che verifica una chiamata p/invoke specificata in modo errato. Questo articolo MSDN fornisce informazioni dettagliate su questo: http://msdn.microsoft.com/en-us/library/0htdy0k3.aspx. Stephen Cleary merita il merito di averlo identificato in questo post: pinvokestackimbalance -- how can I fix this or turn it off?