2010-03-12 1 views
3

Voici le code en C++ dll:C# wrapper de C++ dll; "Échec de vérification d'exécution # 0 - La valeur d'ESP n'a pas été enregistrée correctement lors d'un appel de fonction." erreur

extern "C" _declspec(dllexport) int testDelegate(int (*addFunction)(int, int), int a, int b) 
{ 
    int res = addFunction(a, b); 
    return res; 
} 

et est ici le code en C#:

public delegate int AddIntegersDelegate(int number1, int number2); 

public static int AddIntegers(int a, int b) 
{ 
    return a + b; 
} 

[DllImport("tester.dll", SetLastError = true)] 
public static extern int testDelegate(AddIntegersDelegate callBackProc, int a, int b); 

public static void Main(string[] args) 
{ 
    int result = testDelegate(AddIntegers, 4, 5); 
    Console.WriteLine("Code returned:" + result.ToString()); 
} 

Quand je commence cette petite application, je reçois le message de l'en-tête de ce poste . Quelqu'un peut-il aider, s'il vous plaît?

Merci à l'avance,

D

Répondre

11

Adam est correct, vous avez un décalage sur l'appel convention sur une version 32 bits de Windows. Le pointeur de fonction par défaut à __cdecl, la déclaration de délégué par défaut à CallingConvention.StdCall. La non-concordance empêche le pointeur de la pile d'être correctement restauré lorsque l'appel de délégué revient, déclenchant le diagnostic dans la version de débogage de votre code C/C++.

Pour le fixer sur le côté de C/C:

typedef int (__stdcall * Callback)(int, int); 

extern "C" _declspec(dllexport) int testDelegate(Callback addFunction, int a, int b) 
{ 
    int res = addFunction(a, b); 
    return res; 
} 

Pour résoudre ce problème sur le côté C#:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
    public delegate int AddIntegersDelegate(int number1, int number2); 
+1

Ah, upvoting votre réponse pour 'CallingConvention.Cdecl' comme je l'étais entièrement ignorant cela. –

+0

Les gars, merci beaucoup. Vous avez résolu mon problème. –

+1

Cependant, cela fonctionne pour moi quand, à la place [UnmanagedFunctionPointer (CallingConvention.Cdecl)] public delegate int AddIntegersDelegate (int nombre1, nombre entier2); Je mets: [UnmanagedFunctionPointer (CallingConvention.StdCall)] délégué public int AddIntegersDelegate (int nombre1, entier nombre2); –

0

Il est généralement signifie une « non-concordance d'interface »: la déclaration utilisée pour compiler le client est différent de la version actuelle de dll.

3

L'argument pointeur de fonction de testDelegate doit être marquée par __stdcall, sinon invoquer corrompra la pile (car il utilise différentes conventions d'appel.)