簡體   English   中英

僅 declspec 和 stdcall 與 declspec

[英]declspec and stdcall vs declspec only

我是 C++ dll 導入主題的新手,我的問題可能很簡單,但我在谷歌上找不到。

我有一個非常簡單的 C++ win32 dll:

#include <iostream>

using namespace std;

extern "C"
{
    __declspec(dllexport) void __stdcall DisplayHellowFromDLL()
    {
        cout<<"Hi"<<endl;
    }
}

當我從 C# 調用此方法時,我沒有任何問題,這里是 C# 代碼

namespace UnmanagedTester
{
    class Program
    {
        [DllImport(@"C:\CGlobalDll")]
        public static extern void DisplayHellowFromDLL();

        static void Main(string[] args)
            {
                Console.WriteLine("This is C# program");
                DisplayHellowFromDLL();
            }
        }
    }

正如我所料,output 是:“這是 C# 程序”“嗨”。

現在,如果我將 C function 的聲明更改為:

__declspec(dllexport) void DisplayHellowFromDLL()

沒有__stdcall,我也沒有任何問題,問題是:

我什么時候真的需要 __declspec(dllexport) TYPE __stdcall,什么時候我只能使用 __declspec(dllexport) TYPE?

非常感謝。

你可以這樣想:

  1. __declspec(dllexport)將您的 function 聲明為您的 DLL 導出的公共 function;

  2. __stdcall是一個相當低級的細節,指的是 function 采用的“調用約定”; 具體來說, __stdcall表示被調用者清理堆棧;

  3. __stdcall的替代方法是__cdecl ,這意味着:調用者清理堆棧。

__cdecl是“自然”的 C 調用約定; 它支持可變參數函數的定義(如 printf)。

__stdcall是 DLL 函數的默認調用約定,因此如果您僅通過其 DLL API 調用這些函數,則無需指定它。

這應該解釋你正在觀察什么。

它是偶然工作的,因為 function 不需要任何 arguments。 一旦您在確實需要 arguments 的 function 上執行此操作,您就會開始走運。 該調用將使堆棧不平衡,非常不健康。 調試時會收到pInvokeStackImbalance MDA 警告 不平衡的堆棧可能會在一段時間內被忽視,否則會導致您的程序在發布版本中崩潰。

如果您使用其他約定編譯調用代碼,則需要指定調用約定。 否則默認值將起作用。

Ilya,你也可以在項目屬性 -> 配置屬性 -> C/C++ -> 高級 -> 調用約定中設置默認調用約定。 如果您的項目中的默認調用約定已設置為 __stdcall (/Gz),則添加 __std

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM