ily*_*w77 14 c# c++ dllimport stdcall
我是C++ DLL导入主题的新人,可能是我的问题很容易但我在谷歌上找不到它.
我有一个非常简单的C++ win32 dll:
#include <iostream>
using namespace std;
extern "C"
{
__declspec(dllexport) void __stdcall DisplayHellowFromDLL()
{
cout<<"Hi"<<endl;
}
}
Run Code Online (Sandbox Code Playgroud)
当我从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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如我所料,输出是:"这是C#程序""嗨".
现在,如果我将C函数的声明更改为:
__declspec(dllexport) void DisplayHellowFromDLL()
Run Code Online (Sandbox Code Playgroud)
没有__stdcall,我也没有任何问题,问题是:
我什么时候才真正需要__declspec(dllexport)TYPE __stdcall,何时我只能使用__declspec(dllexport)TYPE?
非常感谢.
ser*_*gio 16
你可以这样想:
__declspec(dllexport) 将您的函数声明为DLL导出的公共函数;
__stdcall是一个相当低级的细节,指的是该函数采用的"调用约定"; 具体来说,__stdcall意味着被调用者清理堆栈;
替代__stdcall是__cdecl,这意味着:调用者清理堆栈.
__cdecl是"自然的"C调用约定; 它支持vararg函数的定义(如printf).
__stdcall 是DLL函数的默认调用约定,因此如果您只是通过其DLL API调用这些函数,则不需要指定它.
这应该解释你在观察什么.
它是偶然的,因为该函数不带任何参数.只要你做到这一点上,一个函数不带参数,你会开始运行的运气了.通话将使堆栈失衡,非常不健康.调试时,您将收到pInvokeStackImbalance MDA警告.不平衡的堆栈可能会暂时被忽视,它往往会在Release版本中崩溃您的程序.