首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >declspec和stdcall vs.仅declspec

declspec和stdcall vs.仅declspec
EN

Stack Overflow用户
提问于 2011-06-14 02:03:58
回答 4查看 13.4K关注 0票数 14

我是一个新人到C++ dll导入话题,可能是我的问题很简单,但我在谷歌上找不到它。

我有一个非常简单的C++ win32 dll:

代码语言:javascript
复制
#include <iostream>

using namespace std;

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

当我从C#调用这个方法时,我没有遇到任何问题,下面是C#代码

代码语言:javascript
复制
namespace UnmanagedTester
{
    class Program
    {
        [DllImport(@"C:\CGlobalDll")]
        public static extern void DisplayHellowFromDLL();

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

正如我所料,输出是:"This is C# program“"Hi”。

现在,如果我将C函数的声明改为:

代码语言:javascript
复制
__declspec(dllexport) void DisplayHellowFromDLL()

没有__stdcall,我也不会有任何问题,问题是:

什么时候我真的需要__declspec(dllexport)类型的__stdcall,什么时候我只能使用__declspec(dllexport)类型?

非常感谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-14 02:07:12

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

票数 3
EN

Stack Overflow用户

发布于 2011-06-14 02:22:29

你可以这样想:

  1. __declspec(dllexport)将您的函数声明为一个公共函数,您的DLL exports;
  2. __stdcall是一个相当底层的详细信息,它引用了该函数所采用的“调用约定”;具体地说,__stdcall表示被调用者将stack;
  3. alternative清理为__stdcall is __cdecl,这意味着:调用者清理堆栈。

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

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

这应该可以解释你所观察到的东西。

票数 17
EN

Stack Overflow用户

发布于 2011-06-14 02:23:48

它的工作是偶然的,因为函数不接受任何参数。一旦你在一个接受参数的函数上这样做,你就会开始走运。调用会使堆栈不平衡,非常不健康。当你调试的时候,你会得到pInvokeStackImbalance MDA warning。不平衡的堆栈可能会在一段时间内不被注意到,它往往会在发布版本中使您的程序崩溃。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6334283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档