Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我应该更喜欢“吗?”;“违约”;当我不';我真的不在乎电话会议吗? 我们有一个巨大的C++代码库,有很多COM对象。每个暴露于COM的函数必须有\uu stdcall调用约定(通常是STDMETHODCALLTYPEmacro),因此我们有许多标记为STDMETHODCALLTYPE的函数 现在我看到的函数不是直接调用COM,而是只从C++代码中调用,这个函数在签名中也有 STDMODCALLYTYPE 宏。我完全相信宏在那个里是无用的——并没有通过COM调用那个函数_C++_Windows_Visual C++_Com_Calling Convention - Fatal编程技术网

我应该更喜欢“吗?”;“违约”;当我不';我真的不在乎电话会议吗? 我们有一个巨大的C++代码库,有很多COM对象。每个暴露于COM的函数必须有\uu stdcall调用约定(通常是STDMETHODCALLTYPEmacro),因此我们有许多标记为STDMETHODCALLTYPE的函数 现在我看到的函数不是直接调用COM,而是只从C++代码中调用,这个函数在签名中也有 STDMODCALLYTYPE 宏。我完全相信宏在那个里是无用的——并没有通过COM调用那个函数

我应该更喜欢“吗?”;“违约”;当我不';我真的不在乎电话会议吗? 我们有一个巨大的C++代码库,有很多COM对象。每个暴露于COM的函数必须有\uu stdcall调用约定(通常是STDMETHODCALLTYPEmacro),因此我们有许多标记为STDMETHODCALLTYPE的函数 现在我看到的函数不是直接调用COM,而是只从C++代码中调用,这个函数在签名中也有 STDMODCALLYTYPE 宏。我完全相信宏在那个里是无用的——并没有通过COM调用那个函数,c++,windows,visual-c++,com,calling-convention,C++,Windows,Visual C++,Com,Calling Convention,我是否应该删除\uu stdcall,使其成为“默认”调用约定函数?如何做出这样的决定?我的方法是对内部代码使用默认的编译器调用约定,对跨模块边界导出的任何方法使用定义明确的调用约定 大多数编译器的默认调用约定充分利用了寄存器,这是出于性能原因,因此在适当的情况下使用它有很多优点。由于不需要指定约定即可获得默认值,因此它还可以使代码更直观 对于导出的函数,显然需要指定约定。如果你正在制作一个你预期会从C语言或C++语言中调用的库,那么使用STDCALL是常规的。如果您只期望C或C++客户端,那么

我是否应该删除
\uu stdcall
,使其成为“默认”调用约定函数?如何做出这样的决定?

我的方法是对内部代码使用默认的编译器调用约定,对跨模块边界导出的任何方法使用定义明确的调用约定

大多数编译器的默认调用约定充分利用了寄存器,这是出于性能原因,因此在适当的情况下使用它有很多优点。由于不需要指定约定即可获得默认值,因此它还可以使代码更直观


对于导出的函数,显然需要指定约定。如果你正在制作一个你预期会从C语言或C++语言中调用的库,那么使用STDCALL是常规的。如果您只期望C或C++客户端,那么CCDL可能是最常见的约定。

< P> com组件显式设置调用约定的唯一原因是因为它是跨DLL边界使用的。 因此,我的建议是放弃调用约定的显式设置,并通过编译器设置进行设置。
一般来说:
如果函数导出为DLL,请设置一个宏,该宏在标头中定义调用约定。这可以防止DLL用户在链接到DLL时使用错误的调用约定。显式重写编译器设置。
不要在本地函数上使用任何调用对流。可以通过编译器开关设置约定。如果您决定显式地设置一个,那么在所有函数上都这样做。然后,您仍然可以在中心位置更改呼叫约定。

当然,如果它有意义,或者您需要一些特殊的调用约定,例如用于优化的fastcall,那么您也需要显式地进行设置。

您可以通过搜索与解决方案关联的ODL文件,查看映射是否被引用。如果没有,它就没有接口,您可以更改调用约定。有一种风险是,其他人假设所有函数都是使用此调用约定设置的,他们可能会在以后添加一个接口。

当Windows从u cdecl切换到u stdcall作为默认调用约定时,产品的大小下降了约10%。这种节省完全与调用stdcall方法后删除堆栈调整有关(_cdecl是“调用者调整堆栈以删除参数”调用约定,_stdcall是“调用者调整堆栈以删除参数”调用约定,因为呼叫者比被呼叫者多,所以切换会减少二进制文件的大小)

使用u stdcall的缺点是没有参数的变量(因为被调用者调整堆栈,他们不知道调用者指定了多少参数)

一句话:从“默认”调用约定切换到uu stdcall可以减少二进制文件的大小。这对你来说可能重要,也可能不重要


然而,正如上面提到的mkaes,如果您的代码曾经在另一个编译器中被访问(例如,如果您将一个.lib文件交付给其他人),那么声明所使用的调用约定是绝对重要的

您是否已启用和启用?如果是这样,并且您没有从DLL导出函数或传递指向它的指针,那么编译器可能会为该函数生成自定义调用约定或将其内联(即使它没有在头文件中定义).

实际上,您还需要指定调用约定库-您不能确定调用方是否始终使用与您相同的编译器设置。当编译器的默认调用约定发生变化(它在过去发生过)并且您没有重新编译所有代码时会发生什么情况?@Larry通常在您使用库时,头文件定义调用约定。我认为这是理所当然的。还是我误解了你?我的意思很清楚,当你在进口的时候,你在出口时是明确的要求同样适用。但通常在编写代码时,库的作者会编写导入头文件和相关的.lib以及实际的DLL。不,你没有误解我。当我阅读您的回复时,我认为您建议库应该使用默认的调用约定,而不是显式地声明调用约定。混淆的关键是“module”一词——大多数时候人们认为“modules”是DLL。@Larry我所说的module是指DLL或EXE,所以和你一样。我肯定不是建议您在导出时指定调用约定,而不是在导入时指定。我的观点是,即使是库也需要声明和修复调用约定。在stone中锁定调用约定唯一不安全的时候是在编译没有.libs的独立程序时。