2010-02-20 10 views
3

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.

+0

Vous n'avez pas besoin du mot-clé dangereux sur la signature pinvoke. PInvoke gère le marshalling de .net à natif – zebrabox

+2

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)] –

+0

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é. –

Répondre

5

La convention d'appel est erronée. Si la suppression des arguments int ne déclenche pas la MDA alors il 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 exportées, vous pouvez envisager de modifier dans le code C/C++, si vous pouvez.

2

en C++ est un long 32 bits. En C# c'est 64 bits. Utilisez int dans votre déclaration C#.

Vous pouvez également essayer d'ajouter __stdcall à la fonction C++. Voir: What is __stdcall?

+0

Très bon aperçu, et vous devez être correct sur les paramètres que leur suppression complète résout le problème. Le simple fait de les déclarer comme int dans C# ne le permet pas. –

+0

Voir mise à jour ..... –

0

en C# long signifie 64 bits int tandis que dans C++ signifie une longueur de 32 bits int, vous devez changer votre déclaration de PInvoke à

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

Vous pouvez également essayer de changer votre C++ déclaration à stdcall, c'est la convention d'appel utilisée par la plupart des fonctions exportées dans l'environnement Windows.

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

Malheureusement, cela ne résout pas le problème. Merci de m'avoir dirigé vers le type Marshalling, mais je fais des recherches maintenant. –

Questions connexes