问题标签 [stdcall]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
3814 浏览

c++ - 为什么需要使用“WINAPI*”作为为 DLL 中的函数声明函数指针的语法

我有一个 C++ 控制台应用程序和一个 DLL。在 C++ 应用程序中,我看到以下代码片段::

在高层次上,我理解我们正在获取指向 a.DLL“function_1()”中函数的函数指针。

但是想了解上面代码片段中的第一 2 行 ::

2 个问题 :: 1) 名称“functABC”只是一个随机函数指针名称吗?
2)我们在这两条线上在技术上做了什么。声明函数指针。
3) 为什么我们需要在第一行的函数指针声明中使用 WINAPI*。

提前致谢。

0 投票
1 回答
86 浏览

c - 是否有必要关心不是从 dll 导出的函数的调用约定

我目前正在开展一个项目,该项目涉及创建一些C将交付给客户的 DLL 库。DLL 导出一些函数,所有导出的函数都使用__stdcall调用约定。该库还包含一些未导出但由导出函数使用的函数。有必要关心这些本地函数的调用约定吗?我可以将本地函数的调用约定保留为默认值吗?

0 投票
1 回答
373 浏览

c# - 创建与 Windows 服务通信的非托管 DLL(在 C++ 中)?

我创建了一个捕获密码更改的 dll 文件(使用 C++)。现在我需要将它发送到使用 WCF 服务的 Windows 服务(由我使用 C# 创建)。如何与服务通信?

(dll是原始的,没有类,并且使用_stdcall,因为它需要被Windows操作系统调用)

或者还有其他方法可以做到吗?dll本身可以用C#编写吗?(非托管)

0 投票
0 回答
65 浏览

g++ - 链接器忽略来自 g++ 的选项

我正在尝试使用 g++ 创建没有 @-suffix 的目标文件:

g++ -Wl,--add-stdcall-alias -c test.cpp

或者

g++ -Wl,--kill-at -c test.cpp

但没有一个选项有效。

使用:MinGW32 与 g++ v4.4、ld v2.19.1

谢谢!

0 投票
1 回答
265 浏览

c - stdcall 函数的这个 asm 如何从堆栈中清除 args?

我有简单的代码。StdCall__stdcallCdeclCall__cdecl

StdCall 的 main() Disassabmbly 的一部分(Main清除 StdCall 的堆栈)

CdeclCall 的 main() 的 Disassabmbly 的一部分(Main为CdeclCall清除堆栈)


现在,StdCall 负责从堆栈中删除其参数,但反汇编不会显示任何弹出 ag 以清除/清理堆栈的代码。

StdCall 的反汇编

是生成清除堆栈代码的运行时活动__stdcall还是我错误地理解了概念?

0 投票
1 回答
3432 浏览

gcc - GCC 忽略调用约定属性

有谁知道为什么这不起作用?

当我尝试用 C++11 方言编译时,它说:

“警告:'stdcall' 属性指令被忽略 [-Wattributes]”

这是为什么?我有一个真正需要 stdcall 调用约定的函数。GCC 中的默认调用约定是 cdecl。有什么建议么?

0 投票
1 回答
229 浏览

c - 调用 Windows API 函数 (stdcall) 的符号扩展规则是什么?这是从 Go 调用 WInAPI 所需要的,它对 int 类型有严格要求

糟糕,当我做出这个答案时,我忘记了一件事,这是我对自己不太确定的事情,而且我似乎无法在 MSDN 和 Google 以及 Stack Overflow 搜索中找到相关信息。

在 Windows API 中有很多地方使用负数,或者数字太大而无法放入有符号整数;例如,CW_USEDEFAULTINVALID_HANDLE_VALUEGWLP_USERDATA,等等。在 C 的世界里,一切都很好,花花公子:语言的整数提升规则来拯救。

但是在 Go 中,我必须将所有参数传递给函数 as uintptr(相当于 C 的uintptr_t)。函数的返回值也是这样返回的,然后我需要比较一下。Go 不允许整数提升,也不允许您在编译时将有符号常量表达式转换为无符号常量。

现在,我在我的UI 库中设置了一些 jerry-rig来处理这些常量。(这里是这个解决方案实际效果的一个例子。)但是,我对这个解决方案不太满意;在我看来,它就像在假设关于 ABI 的事情,我想绝对确定我在做什么。

所以我的问题是:将签名值传递给 Windows API 函数时如何处理它们以及返回时如何处理它们?

我所有的常量都是自动生成的(示例输出)。自动生成器使用C ffi,我不想将其用于主项目,因为我可以直接调用 DLL(这也使交叉编译更容易,至少在今年剩下的时间里)。如果我能以某种方式利用它,例如通过将所有内容都变成表单的 C 端变量

那会很有帮助。但如果没有这个答案,我不能这样做。

谢谢!

更新

IRC 上有人说不同(重新格式化以避免水平滚动):

基本上是这样,但专门用于 Windows API 互操作,用于传入的参数,并且不管 uintptr 大小。

0 投票
2 回答
3441 浏览

c - 为什么微软定义WINAPI、CALLBACK、APIENTRY都指__stdcall?

对于为负责定义这些宏的 Microsoft 团队工作过、认识工作过的人或与 Microsoft 团队有任何关系的任何人来说,这是一个好奇的问题。

我了解__stdcall是什么,并且知道为什么要使用它,但我只是不明白为什么微软会为同一件事制作三个单独的宏。我能看到的唯一好处是在源文件中提供一些语义含义,但除此之外,据我所知,它没有提供其他好处。显然这样做是有道理的,我只是想知道它是什么!:)

0 投票
2 回答
740 浏览

c++ - 是否可以在 __stdcall 中有一个导出的函数并且名称未损坏?

我正在开发一个项目来生成一个用于离线测试的虚拟 DLL。我们有真正的 DLL 及其头文件,尽管它们看起来不兼容。DLL 中的名称未被破坏,但函数前向声明声明被调用为__stdcall

例子.h

Dependency Walker 中的 example.dll:

据我所知,如果可以在__stdcall约定中导出一个函数,它的名称应该在依赖 walker 中读取为:

这是否意味着我们的头文件与编译的 DLL 不对应,还是我遗漏了什么?

最终,我如何形成虚拟函数的导出,使其行为方式与我正在模拟的真实 DLL 相同?

0 投票
2 回答
419 浏览

gcc - 为什么当我调用带参数的 Win32 函数时 GCC 使用帧指针?

当我使用 GCC 和 -fomit-frame-pointer 选项编译 32 位 C 代码时,不使用帧指针 (ebp),除非我的函数使用 stdcall 和至少一个参数调用 Windows API 函数。

例如,如果我只使用 Windows API 中的 GetCommandLine(),它没有参数/参数,GCC 将省略帧指针并将 ebp 用于其他事情,从而加快代码速度并且没有那个无用的序言。

但是当我调用一个接受至少一个参数的 stdcall Win32 函数时,GCC 完全忽略了 -fomit-frame-pointer 并使用了帧指针,并且代码在检查中更糟糕,因为它不能将 ebp 用于一般用途事物。更不用说我发现帧指针毫无意义。我的意思是,我想编译发布和分发,我为什么要关心调试?(如果我想调试,我只会在重现错误后使用调试版本)

我的堆栈肯定不包含像 alloca 这样的动态分配。那么,堆栈具有已定义的结构,但尽管我有选择,但 GCC 还是选择了愚蠢的方法?我是否缺少一些东西来强制它不使用帧指针?

我对它的第二个看法是它拒绝对 Win32 函数使用“推送”指令。我尝试过的所有其他编译器,他们使用推送指令来推送堆栈,从而产生更好更紧凑的代码,更不用说它是推送 stdcall 参数的最自然方式。然而 GCC 顽固地使用“mov”指令在每个位置手动移动,相对于 esp 偏移,因为它需要保持堆栈指针完全静止。stdcall 对调用者来说很容易,但 GCC 完全忽略了 stdcall 的意义,因为它在与它交互时会生成这个糟糕的代码。更糟糕的是,由于堆栈指针是静态的,它仍然使用帧指针?只是为什么?

我试过-mpush-args,它什么也没做。

我还注意到,如果我让我的堆栈大到足以超过一页(4096 字节),GCC 将添加一个函数的序言,该函数除了“按位或”每 4096 字节零堆栈(什么都不做) . 我假设它是为了触摸堆栈并在堆栈被保留的情况下自动提交带有页面错误的内存?不幸的是,即使我将堆栈的初始提交(不是保留)设置为足够高以容纳我的堆栈,它也会这样做,更不用说一开始甚至不需要这样做。最好的冗余代码。

这些错误在 GCC 中吗?还是我在选项中缺少的东西?我应该使用其他东西吗?如果我遗漏了一些选项,请告诉我。

我真的希望我不必为了调用 stdcall 函数和使用推送指令而制作内联 asm 宏(我猜这也将避免帧指针)。对于今天应该在编译器中使用的如此基本的东西来说,这听起来真的有点矫枉过正。是的,我使用的是 GCC 4.8.1,所以不是一个古老的版本。

作为额外的问题,是否可以强制 GCC 在函数序言中不将寄存器保存在堆栈上?我将自己的直接入口点与 -nostartfiles 参数一起使用,因为它是一个纯 Windows 应用程序,并且无需标准 lib 启动就可以正常工作。如果我使用属性((noreturn)),它会丢弃恢复寄存器的结尾,但它仍然会在序言时将它们推送到堆栈上,我不知道是否有办法强制它不为这个入口点保存寄存器功能。不管怎样,至少没什么大不了的,我猜它只会感觉更完整。谢谢!