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.

War es hilfreich?

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:

  1. __declspec(dllexport) deklariert Ihre Funktion als öffentliche Funktion, die Ihre DLL exportiert.

  2. __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;

  3. 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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top