declspec 和 stdcall 与仅 declspec

发布于 11-15 08:52 字数 964 浏览 3 评论 0原文

我是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

是伱的2024-11-22 08:52:37

您可以这样想:

  1. __declspec(dllexport) 将您的函数声明为 DLL 导出的公共函数;

  2. __stdcall 是一个相当低级的细节,指的是该函数采用的“调用约定”;具体来说,__stdcall 意味着被调用者清理堆栈;

  3. __stdcall 的替代方案是 __cdecl,这意味着:调用者清理堆栈。

__cdecl 是“自然的”C 调用约定;它支持可变参数函数的定义(如 printf)。

__stdcall 是 DLL 函数的默认调用约定,因此如果您只想通过 DLL API 调用这些函数,则无需指定它。

这应该可以解释您所观察到的情况。

You can think of it like this:

  1. __declspec(dllexport) declares your function as a public function that your DLL exports;

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

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

著墨染雨君画夕2024-11-22 08:52:37

它的工作是偶然的,因为该函数不接受任何参数。一旦您在一个确实接受参数的函数上执行此操作,您就会开始失去运气。该调用会使堆栈不平衡,非常不健康。调试时,您会收到 pInvokeStackImbalance MDA 警告。否则,不平衡的堆栈可能会在一段时间内被忽视,它往往会导致发布版本中的程序崩溃。

It works by accident because the function doesn't take any arguments. As soon as you do this on a function that does take arguments you'll start running out of luck. The call will leave the stack imbalanced, very unhealthy. You'd get the pInvokeStackImbalance MDA warning when you debug. An imbalanced stack can otherwise go unnoticed for a while, it tends to crash your program in the Release build.

就是爱搞怪2024-11-22 08:52:37

如果使用其他约定编译调用代码,则需要指定调用约定。否则,默认值将起作用。

You need to specify the calling convention if you compile the calling code with some other convention. Otherwise the default will work.

尛丟丟2024-11-22 08:52:37

Ilya,您还可以在“项目属性”->“项目属性”中设置默认调用约定。配置属性-> C/C++->高级->调用约定。
如果项目中的默认调用约定已设置为 __stdcall (/Gz),则添加 __std

Ilya, you can also set the default calling convention in Project Properties -> Configuration Properties -> C/C++ -> Advanced -> Calling Convention.
If the default calling convention in your project is already set to __stdcall (/Gz), then adding __std

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文