问题标签 [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-studio-2008 - 在 Visual Studio 中使用自定义 prolog 和 epilog 代码编写裸函数
我正在一个 dll 中编写一些插件代码,该代码由我无法控制的主机调用。
主机假定插件被导出为 __stdcall 函数。主机被告知函数的名称和它期望的参数的详细信息,并通过 LoadLibrary、GetProcAddress 和手动将参数推送到堆栈上动态地整理对它的调用。
通常插件 dll 会暴露一个常量接口。我的插件公开了一个在 dll 加载时配置的接口。为了实现这一点,我的插件公开了一组在编译 dll 时定义的标准入口点,并根据需要将它们分配给正在公开的内部功能。
每个内部函数都可以采用不同的参数,但是这会与物理入口点名称一起传递给主机。我的所有物理 dll 入口点都被定义为采用单个 void * 指针,我自己通过从第一个参数的偏移量和已传达给主机的已知参数列表中处理来自堆栈的后续参数。
主机可以使用正确的参数成功调用我的插件中的函数并且一切正常......但是,我知道a)我的函数没有像定义的那样清理堆栈作为 __stdcall 函数,它采用 4 字节指针,因此即使调用者将更多参数压入堆栈,它们也总是在末尾执行“ret 4”。b) 我无法处理不带参数的函数,因为 ret 4 会在我返回时从堆栈中弹出太多 4 个字节。
从我的插件中追踪到主机的调用代码后,我可以看到实际上 a) 没什么大不了的;主机丢失了一些堆栈空间,直到它从调度调用返回,此时它清理了清理我的垃圾的堆栈帧;然而...
我可以通过切换到 __cdecl 而根本不清理来解决 b)。我假设我可以通过切换到裸函数并编写我自己的通用参数清理代码来解决 a)。
因为我知道刚刚调用的函数使用的参数空间量,所以我希望它会像这样简单:
但这不起作用,因为 ret 需要一个编译时间常数......有什么建议吗?
更新:
感谢罗布肯尼迪的建议,我得到了这个,这似乎工作......
这看起来对吗?
c++ - C/C++ 中有哪些不同的调用约定,各自的含义是什么?
在 C/C++ 中有不同的调用约定:stdcall
、extern
、pascal
等。有多少这样的调用约定可用,每个是什么意思?有没有描述这些的链接?
c++ - 为什么要在 C++ 函数中最后添加默认参数?
为什么要在 C++ 函数中最后添加默认参数?
visual-studio-2008 - 为什么在 VS2003 中编译的 .lib 无法与使用 VS2008 编译的代码链接?
在尝试将使用 Visual Studio Express 2008 编译的一组代码与使用 Visual Studio 2003 编译的 .lib 链接时,我们刚刚获得了一次有趣的体验。全部使用 C++。准确地说,是在VS2003中编译成.lib的SystemC 2.2.0内核,在VS2008中编译的SystemC模型。
在链接时,我们不断收到错误,即在链接期间未找到 SystemC.lib 文件(即在 VS2003 中编译)中的一些符号。我们得到的错误是这样的(在一些变体中):
从各种线索中挖掘,事实证明 .lib 期望找到的函数是这样的:
虽然 VS2008 试图链接的库文件 (libcpmt.lib) 使用了不同的调用约定:
我试图弄清楚为什么会发生这种不兼容,但最后我放弃了,在 VS2008 中重新编译了完全相同的 Visual Studio 项目,并使用了 SystemC.lib 而不是 VS2003 中的那个。现在,一切都很顺利。
所以这里的基本问题是:从 VS2003 到 VS2008 发生了什么变化,会导致某些函数改变它们的调用约定?是否有一些魔术标志可以给 VS2008 中的链接器以使用其他库,其中函数具有与 VS2003 编译中相同的调用约定?
更新,到目前为止的答案摘要:微软很可能将 C++(不是 C,只是 C++)ABI 从 Visual Studio 的一个主要版本更改为下一个。库中还可能存在其他导致不兼容的更改。最好的建议是为每个版本的 VS 重新编译 .lib。本质上,只需将其以源代码形式发送给用户,并让他们使用他们碰巧安装的任何版本的 VS 在本地编译它。
通过使用以下建议发现了基本问题:
请注意,这些问题没有回答这个问题:
c++ - 使用 boost::function_types 的函数调用约定
我最近一直在尝试 boost::function_types 库,但遇到了一些问题。我想找出给定函数的调用约定,但是我不太确定如何做到这一点。这是我到目前为止所拥有的:
这会产生一个关于如何在每个 if 语句中找不到 *_cc 标记值的错误。我怀疑这可能与我定义宏的方式有关;该文档对如何使用编译器设置额外的调用约定不是很清楚......这里的任何帮助将不胜感激。
谢谢,
编辑:让它工作,似乎我需要包含 config/config.hpp,如下所示:
c++ - Error linking with 3rd party static library built with previous version of Visual Studio
I am working on a project that links to a 3rd party static library (herin refered to as EXTERNALLIB). In Visual Studio 2005 I was able to link to EXTERNALLIB and create a usable executable. Now we are using Visual Studio 2008 and I am receiving the following error:
Is there a way for me to tell the compiler to correctly link to EXTERNALLIB? I believe the problem may be related to specific calling conventions (__stdcall, __cdecl, __clrcall, __thiscall). Can I indicate in the new program the correct calling convention for the old library? Is there specific feedback that I can give to our vendor (such as using APIENTRY in the header files) such that this problem does not occur with future compiler upgrades?
The code is writen in C++. I do not have access to the code for EXTERNALLIB and thus I am unable to rebuild it myself.
c - 为什么调用者必须在 cdecl 调用约定中清除堆栈?
来自:http ://en.wikipedia.org/wiki/X86_calling_conventions
为什么我们需要显式地将 12 添加到 ESP 以清除堆栈,因为被调用的函数应该已将参数从堆栈中弹出,从而恢复堆栈指针......?
另一个问题:
从理论上讲,有可能在被调用者负责清理权的情况下实现可变参数函数(例如,如果您在寄存器中传递堆栈上的参数数量)?
c# - 使方法静态可以提高性能,在什么情况下?
如果有的话,将参数作为参数传递给静态方法而不是让该方法是非静态的并通过实例成员访问相同的值是否会更快。假设该方法以只读方式访问这些成员。
在所有其他条件相同的情况下,调用静态方法比调用实例方法稍快。
在所有其他条件相同的情况下,调用不带参数的方法比调用带参数的方法稍快。
考虑:
与此等效代码相比:
我想不出这种优化会真正增加任何价值的现实情况,但作为一个思想实验(对于那些喜欢讨论这种事情的人),真的有好处吗?如果是的话有多少参数(什么类型等)以另一种方式平衡?
考虑到这一点,是否还有其他因素?例如,静态方法_thing
作为局部变量而不是字段进行访问。
linux - C calling conventions and passed arguments
When making a function call in Linux (or OS X for that matter), can the callee modify the values of the arguments on the stack? I was under the assumption that since the caller is the one that cleans them up, that they should contain the same values after the function call. However I found that GCC with -O2 was modifying parameters that were passed to it on the stack. I have also looked for documentation including the System V i386 calling conventions, but was unable to find a definitive answer to this.
Here is some sample code I was debugging.
I would assume that GCC modifying that parameter on the stack is fine, but I want to know where it is specified that it can do so.