[英]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?
非常感謝。
你可以這樣想:
__declspec(dllexport)
將您的 function 聲明為您的 DLL 導出的公共 function;
__stdcall
是一個相當低級的細節,指的是 function 采用的“調用約定”; 具體來說, __stdcall
表示被調用者清理堆棧;
__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.