2013-08-22 10 views
0

Quelqu'un sait comment corriger cette erreur?Appel du code non géré à partir du code managé

ERREUR:

A call to PInvoke function 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.

J'utilise P/Invoke pour appeler un code natif à partir d'un code managé. Le code natif est importé via des bibliothèques de liens dynamiques.

étapes sont

  1. Localisation .dll contenant ces fonctions.
  2. Chargement .dll dans la mémoire
  3. Localisation de l'adresse de la fonction dans la mémoire
  4. Transformer cette représentation de la mémoire de l'objet à un format de données (marshalling)

DLL a une fonction avec déclaration

long __stdcall Connect (long,long,long,long,long,long,long,long);` 

Dans mon application, j'ai créé un délégué

[UnmanagedFunctionPointer(CallingConvention.StdCall)] 
private delegate long delConnect(long a, long b, long c, long d, long e, long f, long g, long h);` 

Puis j'ai créé une classe pour dll de chargement et de localiser l'adresse de la fonction dans la mémoire

`NativeMethods de classe statique { [DllImport ("kernel32.dll")] extern public static IntPtr LoadLibrary (string dllToLoad);

[DllImport("kernel32.dll")] 
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); 


    [DllImport("kernel32.dll")] 
    public static extern bool FreeLibrary(IntPtr hModule); 
}` 

Maintenant, quand je suis en train d'utiliser la fonction alors je reçois une erreur

IntPtr pDll = NativeMethods.LoadLibrary("serial.dll"); 
IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "[email protected]"); 
delConnect connect = (delConnect)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall,typeof(delConnect)); 
long check = connect(1, 0, 12, 9600, 0, 0, 8, 0); 
bool result = NativeMethods.FreeLibrary(pDll);` 

J'ai utilisé « _Connect @ 32 » au lieu de « Connect » dans les paramètres de nom de la fonction de la méthode GetProcAddress, parce que du nom mangling.

Quand je suis débogage que je reçois cette erreur dans la déclaration contenant la ligne

long check = connect(1, 0, 12, 9600, 0, 0, 8, 0);

Répondre

1

Le C/C++ est long 32 bits sous Windows, donc un int dans .net. Essayez de le changer (sur Unix, il est plus comme un IntPtr)

[UnmanagedFunctionPointer(CallingConvention.StdCall)] 
private delegate int delConnect(int a, int b, int c, int d, int e, int f, int g, int h); 

Et peut-être au lieu de StdCall essayer Cdecl:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 

Pour la DllImport de l'API Windows, vous devez utiliser

[DllImport("kernel32.dll", CharSet=CharSet.Auto)] 

Donc, si possible, .NET utilise la variante Unicode, et non la variante Ansi.

+0

Merci cela a fonctionné. –

0

Y a-t-il une raison pour laquelle vous utilisez LoadLibrary() plutôt que simplement PInvoquer directement?

Qu'advient-il si vous essayez ceci:

[DllImport("serial.dll", EntryPoint = "[email protected]", CallingConvention = CallingConvention.StdCall)] 
static extern int DelConnect(int a, int b, int c, int d, int e, int f, int g, int h); 

(Note C# int == C++ long, normalement)

Questions connexes