问题标签 [calling-convention]
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.
visual-c++ - 这个接口二进制文件在 MSVC 和 mingw 之间是否兼容?
我正在开发一个允许其用户(位于同一进程中的其他库)交换数据缓冲区和流的库。该库必须可以从 MSVC 和 mingw 代码中使用(更多的兼容性不会受到伤害,但不是绝对必要的)。为了实现这一点,核心功能应该由一个小的、编译器兼容的接口提供,该接口稍后可以被使用客户端代码编译的便利层隐藏。
该库的一个具有挑战性的方面是它必须是可扩展的,以便客户端可以提供自己的缓冲区和流实现,但核心库接口在发布后必须保持稳定。如果您对进一步的背景感兴趣,您可以在论坛主题讨论中阅读它。
我试图了解编译器之间的二进制兼容性问题,但由于我是这个主题的新手,我会对我的结果的评论感兴趣。我对这里的标准定义行为不感兴趣(结构可能无法通过该测试),只对 mingw 和 MSVC 之间的兼容性以及其他编译器之间的兼容性(如果可能的话)感兴趣。
特别是,这些结构是否兼容?它们统一由函数指针组成,所以我认为填充不会成为问题。此外,这里是否需要 stdcall 约定,或者 cdecl 也可以工作?由于两个编译器都默认为 cdecl,我可以不指定它吗?我是不是该?这是我现在所拥有的:
编辑:这个项目已经搁置了一段时间,如果它再次被搁置,可能需要重新考虑。不过我还是把这个问题留了下来,因为我仍然对答案感兴趣。
macos - 为什么在调用 printf 之前将 %eax 归零?
我正在尝试拿起一点x86。我正在使用 gcc -S -O0 在 64 位 mac 上编译。
C中的代码:
输出:
我不明白为什么在调用 'printf' 之前 %eax 被清除为 0。由于printf
将打印的字符数返回到%eax
我的最佳猜测,它被归零以准备它,printf
但我会假设它printf
必须负责准备好它。另外,相比之下,如果我调用自己的函数int testproc(int p1)
,gcc
则不需要准备%eax
。所以我想知道为什么gcc
对待printf
和testproc
不同。
windows - 为什么 Windows x64 调用约定不使用 XMM 寄存器来传递超过 4 个整数参数?
(Microsoft) x64 调用约定指出:
参数在寄存器 RCX、RDX、R8 和 R9 中传递。如果参数是浮点/双精度,则它们在 XMM0L、XMM1L、XMM2L 和 XMM3L 中传递。
这很好,但为什么只是浮动/双打?为什么整数(也可能是指针)不通过 XMM 寄存器传递?
似乎有点浪费可用空间,不是吗?
sockets - 使用套接字时有关函数调用约定的建议
我计划使用套接字在客户端 32 位应用程序和 64 位应用程序之间进行函数调用。
通过套接字接口调用函数、传递变量和返回参数的最佳方案是什么。我可以控制客户端和服务器代码,所以我可以实现任何东西。
我在想,让套接字数据包由以下内容组成: - 1 个字:函数名的长度(字符数) - 字符串:实际的函数名 - 1 个字:函数参数的长度(以字节为单位) - 函数参数
请让我知道,什么是最健壮和可扩展的方法。也许我可以重用编译器、Web 服务或虚拟机调用约定所使用的原则。
提前致谢
c++ - 函数参数列表中的函数调用会加深堆栈吗?
调用 时F(argument_expression)
,argument_expression
在为 F 压栈之前进行评估?
例如,在调用 时F(G(H(arg)))
,编译器是否首先为 H 压栈,评估 H,弹出,然后为 G 压栈等?还是先将堆栈推入 F,然后推入 G,然后推入 H,然后弹回 3 层?
另外,一种方法比另一种更快吗?
c++ - __cdecl 或 __stdcall 在 Windows 上?
我目前正在为 Windows 开发一个 C++ 库,它将作为 DLL 分发。我的目标是最大化二进制互操作性;更准确地说,我的 DLL 中的函数必须可以从使用多个版本的 MSVC++ 和 MinGW 编译的代码中使用,而无需重新编译 DLL。但是,我很困惑哪种调用约定最好,cdecl
或者stdcall
.
有时我会听到诸如“C 调用约定是唯一保证跨编译器相同的”之类的声明,这与“对 的解释存在一些变化cdecl
,特别是在如何返回值方面”之类的声明形成鲜明对比。这似乎并没有阻止某些库开发人员(如libsndfile)在他们分发的 DLL 中使用 C 调用约定,而没有任何明显的问题。
另一方面,stdcall
调用约定似乎定义明确。据我所知,基本上所有 Windows 编译器都必须遵循它,因为它是用于 Win32 和 COM 的约定。这是基于这样的假设,即不支持 Win32/COM 的 Windows 编译器不会很有用。论坛上发布的许多代码片段都将函数声明为,stdcall
但我似乎无法找到一篇清楚地解释原因的帖子。
那里有太多相互矛盾的信息,我运行的每次搜索都会给我不同的答案,这并不能真正帮助我在两者之间做出决定。我正在寻找一个清晰、详细、有争议的解释,说明为什么我应该选择一个而不是另一个(或者为什么两者是等价的)。
请注意,这个问题不仅适用于“经典”函数,还适用于虚拟成员函数调用,因为大多数客户端代码将通过“接口”与我的 DLL 交互,纯虚拟类(遵循此处和此处描述的模式)。
c - C如何返回一个结构?
所以看起来它正在返回局部变量t
,但是这种工作是否可以保证工作,返回时不应该不引用任何局部变量吗?
c++ - __cdecl 和 __declspec 调用约定混淆
我正在为第三方应用程序编写 DLL。主要软件工程师提到应用程序使用 __cdecl (/Gd) 调用约定。我需要确保我使用它。
此外,第三方向我提供了一个 C++ DLL 框架,它导出的函数如下:
我有点困惑。为什么使用 __declspec 约定而不是 __cdedl 导出函数?__declspec 是否支持 _cdecl?
谢谢。
c++ - 我可以在 DLL 中混合使用 __cdecl 导出调用和 __stdcall 导入调用吗?
我正在为第三方应用程序编写模块;应用程序uses __cdecl
调用约定。
同时,我有一个uses __stdcall
调用约定的遗留 DLL。
我可以创建一个在一端exports __cdecl
起作用,而在另一端起imports __stdcall
作用的包装器吗?我还有哪些其他选择?
谢谢,
编辑:
这里有一些额外的信息可以帮助我澄清我的情况。
有一个third_party.exe
需要访问skeleton.dll
. 源代码skeleton.dll包含下面的头文件,使用__cdecl编译。
理想情况下,我会使用框架源代码来开发我的 DLL;不幸的是,将我当前的 VB6 遗留代码移植到 C++ 中太耗时了。鉴于此,我不得不按照本指南破解我的 VB6 代码(这是一种变通方法,但它允许我使用 ActiveX DLL 作为标准 C DLL)。
我对修改后的 VB6 调用约定以及如何修改它不是 100% 有信心。练习使用 __stdcall,并且似乎可以在我开发的测试应用程序中正常工作。但是,当我使用第三方应用程序对其进行测试时,它会正确调用某些函数,但在其他函数中它会崩溃。
架构看起来像:
legacy DLL 生成 dll、lib 和 def 文件;没有头文件。
c - __stdcall 名称装饰的语法是什么?
我有一个调用一组函数的程序,如下所示:
如果名称修饰不匹配,链接器会显示如下错误:
我的理解是_stdcall
语法是一个'_' + 'name of the function' + '@' + 'number of arguments * 4'
.
那么,为什么链接器要求进行?VB_Create@@YGHPAD@Z
名称修饰呢?这是什么标准?