declspec 和 stdcall 与仅 declspec
我是 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();
}
}
}
正如我预期的那样,输出是:“这是 C# 程序”“嗨”。
现在,如果我将 C 函数的声明更改为:
__declspec(dllexport) void DisplayHellowFromDLL()
没有 __stdcall,我也没有任何问题,问题是:
什么时候我真正需要 __declspec(dllexport) TYPE __stdcall 以及什么时候我只能使用 __declspec(dllexport) TYPE ?
多谢。
I'm a new person to C++ dll import topic and may be my question is very easy but I can not find it on google.
I have a very simple C++ win32 dll:
#include <iostream>
using namespace std;
extern "C"
{
__declspec(dllexport) void __stdcall DisplayHellowFromDLL()
{
cout<<"Hi"<<endl;
}
}
When I call this method from C# I do not have any problem, here is 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();
}
}
}
As I expected the output is: "This is C# program" "Hi".
Now if I change the declaration of C function as:
__declspec(dllexport) void DisplayHellowFromDLL()
without __stdcall, I do not have any problem as well, and the question is:
When do I really need __declspec(dllexport) TYPE __stdcall and when I can use only __declspec(dllexport) TYPE ?
Thanks a lot.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(4)
它的工作是偶然的,因为该函数不接受任何参数。一旦您在一个确实接受参数的函数上执行此操作,您就会开始失去运气。该调用会使堆栈不平衡,非常不健康。调试时,您会收到 pInvokeStackImbalance MDA 警告。否则,不平衡的堆栈可能会在一段时间内被忽视,它往往会导致发布版本中的程序崩溃。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您可以这样想:
__declspec(dllexport)
将您的函数声明为 DLL 导出的公共函数;__stdcall
是一个相当低级的细节,指的是该函数采用的“调用约定”;具体来说,__stdcall 意味着被调用者清理堆栈;__stdcall
的替代方案是__cdecl
,这意味着:调用者清理堆栈。__cdecl
是“自然的”C 调用约定;它支持可变参数函数的定义(如 printf)。__stdcall
是 DLL 函数的默认调用约定,因此如果您只想通过 DLL API 调用这些函数,则无需指定它。这应该可以解释您所观察到的情况。
You can think of it like this:
__declspec(dllexport)
declares your function as a public function that your DLL exports;__stdcall
is a rather low-level detail that refers to the "calling convention" adopted by that function; specifically,__stdcall
means that the callee cleans the stack;alternative to
__stdcall
is__cdecl
, which means: the caller cleans the stack.__cdecl
is the "natural" C calling convention; it supports the definition of vararg functions (like printf).__stdcall
is the default calling convention for DLL functions, so you don't need specify it if you are only going to call those functions through their DLL API.This should explain what you are observing.