Un appel à la fonction PInvoke a déséquilibré la stack lors de l’inclusion d’une DLL C dans C #

J’ai écrit une DLL C et du code C # pour tester cette DLL et en exécuter les fonctions. Je ne connais pas très bien ce processus et je reçois une exception PInvokeStackImbalance chaque fois que ma fonction DLL est appelée à partir du code source C #. Le code est le suivant (j’ai commenté le plus de code pour isoler ce problème):

Code d’inclusion C #:

using System; using System.Runtime.InteropServices; using System.IO; namespace TestConsoleGrids { class Program { [DllImport("LibNonthreaded.dll", EntryPoint = "process")] public unsafe static extern void process( long high, long low); static void Main(ssortingng[] args) { System.Console.WriteLine("Starting program for 3x3 grid"); process( (long)0, (long)0 ); System.Console.ReadKey(); } } } 

Code de fonction DLL C ++

 extern "C" __declspec(dllexport) void process( long high, long low ); void process( long high, long low ) { // All code commented out } 

Visual Studio a généré le code dllmain (je ne comprends pas cette construction, donc je l’inclus)

 // dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } 

Les détails de l’exception sont les suivants:

Un appel à la fonction PInvoke ‘TestConsoleGrids! TestConsoleGrids.Program :: process’ a déséquilibré la stack. Cela est probablement dû au fait que la signature PInvoke gérée ne correspond pas à la signature cible non gérée. Vérifiez que la convention d’appel et les parameters de la signature PInvoke correspondent à la signature non gérée cible.

La convention d’appel est incorrecte. Si la suppression des arguments int ne déclenche pas le MDA, alors c’est Cdecl:

  [DllImport("LibNonthreaded.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void process(int high, int low); 

Ce n’est pas la convention d’appel standard pour les fonctions DLL exscopes, vous pouvez envisager de la modifier dans le code C / C ++, si vous le pouvez.

En C ++, long est 32 bits. En C # c’est 64 bits. Utilisez int dans votre déclaration C #.

Vous pouvez également essayer d’append __stdcall à la fonction C ++. Voir: Qu’est-ce que __stdcall?

en C # long signifie 64 bits int alors qu’en C ++ long signifie 32 bits int, vous devez changer votre déclaration pinvoke en

  [DllImport("LibNonthreaded.dll", EntryPoint = "process")] public unsafe static extern void process( int high, int low); 

Vous pouvez également essayer de modifier votre déclaration C ++ en stdcall, qui est la convention d’appel utilisée par la plupart des fonctions exscopes dans l’environnement Windows.

  __stdcall __declspec(dllexport) void process( long high, long low );