J'ai écrit une DLL C et du code C# pour tester cette DLL et y exécuter des 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 (je l'ai commenté la plupart du code pour isoler ce problème):Un appel à la fonction PInvoke a déséquilibré la pile lors de l'inclusion d'une DLL C dans C#
C# Code d'inclusion:
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(string[] args)
{
System.Console.WriteLine("Starting program for 3x3 grid");
process((long)0, (long)0);
System.Console.ReadKey();
}
}
}
C++ DLL Code de fonction
extern "C" __declspec(dllexport) void process(long high, long low);
void process(long high, long low)
{
// All code commented out
}
Visual Studio code généré DllMain (Je ne comprends pas cette construction, donc je l'inclue)
// 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 t Les exceptions sont:
Un appel à la fonction PInvoke 'TestConsoleGrids! TestConsoleGrids.Program :: process' a déséquilibré la pile. 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 paramètres de la signature PInvoke correspondent à la signature non managée cible.
Vous n'avez pas besoin du mot-clé dangereux sur la signature pinvoke. PInvoke gère le marshalling de .net à natif – zebrabox
Avez-vous fait ce que les détails vous indiquent? Vérifié la convention d'appel? Consultez la documentation de la classe DllImportAttribute, http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.aspx, elle possède une propriété CallingConvention, essayez de la définir sur CallingConvention.Cdecl. [DllImport (..., CallingConvention = Callingconvention.Cdecl)] –
Merci Lasse! C'est exactement ce que le problème était. J'ai surtout suivi des tutoriels, et aucun d'entre eux ne l'a mentionné. –