Declspec und STDCall gegen Declspec nur
Frage
Ich bin eine neue Person zu C ++ - DLL -Importthema und kann meine Frage sein, aber ich kann es bei Google nicht finden.
Ich habe eine sehr einfache C ++ Win32 DLL:
#include <iostream>
using namespace std;
extern "C"
{
__declspec(dllexport) void __stdcall DisplayHellowFromDLL()
{
cout<<"Hi"<<endl;
}
}
Wenn ich diese Methode von C# nenne, habe ich kein Problem, hier ist C# Code
namespace UnmanagedTester
{
class Program
{
[DllImport(@"C:\CGlobalDll")]
public static extern void DisplayHellowFromDLL();
static void Main(string[] args)
{
Console.WriteLine("This is C# program");
DisplayHellowFromDLL();
}
}
}
Wie ich erwartet hatte, lautet die Ausgabe: "Dies ist C# Programm" Hi ".
Wenn ich nun die Deklaration der C -Funktion ändere wie:
__declspec(dllexport) void DisplayHellowFromDLL()
Ohne __stdcall habe ich auch kein Problem, und die Frage ist:
Wann brauche ich wirklich __DECLSPEC (dllexport) Typ __stdcall und wann kann ich nur __DECLSPEC (DLEXPORT) -Typ verwenden?
Danke vielmals.
Lösung
Sie müssen die Anrufkonvention angeben, wenn Sie den Anrufcode mit einer anderen Konvention kompilieren. Andernfalls funktioniert der Standard.
Andere Tipps
Sie können es so vorstellen:
__declspec(dllexport)
deklariert Ihre Funktion als öffentliche Funktion, die Ihre DLL exportiert.__stdcall
ist ein ziemlich niedriges Detail, das sich auf die von dieser Funktion übernommene "Anrufkonvention" bezieht; speziell,__stdcall
bedeutet, dass der Callee den Stapel reinigt;als Alternative
__stdcall
ist__cdecl
, was bedeutet: Der Anrufer reinigt den Stapel.
__cdecl
ist die "natürliche" C -Konvention; Es unterstützt die Definition von Vararg -Funktionen (wie printf).
__stdcall
Ist die Standard -Aufrufkonvention für DLL -Funktionen, sodass Sie sie nicht angeben müssen, wenn Sie diese Funktionen nur über ihre DLL -API aufrufen möchten.
Dies sollte erklären, was Sie beobachten.
Es funktioniert zufällig, weil die Funktion keine Argumente enthält. Sobald Sie dies auf eine Funktion tun, die tut Nehmen Sie Argumente, bei denen der Glück ausgeht. Der Anruf lässt den Stapel unausgeglichen, sehr ungesund. Du würdest das bekommen Pinvokestackimbalance MDA Warnung Wenn Sie debuggen. Ein unausgeglichener Stack kann ansonsten für eine Weile unbemerkt bleiben, er stürzt Ihr Programm im Release -Build ab.
Ilya, Sie können auch die Standardaufrufkonvention in Projekteigenschaften -> Konfigurationseigenschaften -> C/C ++ -> Erweitert -> Aufrufkonvention. Wenn die Standardaufrufkonvention in Ihrem Projekt bereits auf __stdcall (/gz) festgelegt ist, fügen Sie __std hinzu