3

vtable 中重载方法的顺序在 win32 编译器中是否始终相同?

问题:我有“接口”(没有数据成员的纯虚拟类)。它们可以通过来自不同编译器的指针来使用(客户端通过调用标准的 c dll 工厂方法获取指针)。除了一种方法外,这在不同的编译器(例如,用 borland 编写的客户端、用 Visual C++ 编写的接口 dll)上都可以正常工作。该方法重载了相同的返回值但不同的参数。此方法有 4 个版本。根据编译客户端的编译器,对该方法的相同调用会返回不同的结果。快速浏览一下汇编代码,我发现 vtable 中似乎有不同的偏移量(我不太擅长阅读汇编程序)。

现在我不知道 - 我是否找到了原因,或者是 borland 只是处理与 Visual Studio 不同的 vtable,一切都是正确的,我必须在其他地方搜索。

最好的问候,谢谢你的回答

托拜厄斯

4

4 回答 4

1

vtable 中的函数顺序是ABI涵盖的内容之一。不幸的是,ABI 不是 C++ 标准的一部分,因此不同的编译器使用不同的 ABI 是很常见的。

于 2010-07-14T06:08:00.987 回答
1

有两个可能的原因:客户端编译器选择的重载与您预期的不同,或者不同的编译器将重载放在不同的 vtable 条目中。

你传递/期望什么参数?重载决议可能是问题吗?

如果是 vtable 条目,那么您可以尝试重命名重载。

在声明接口时,您是否尝试过在目标编译器上使用任何可用的 COM 机制——例如,interface在 MSVC 中使用关键字,并为您的接口类提供 GUID。COM 接口应该按照声明的顺序在 vtable 中具有函数,因此如果它们共享相同的头文件,这在编译器之间是通用的。

于 2010-07-14T06:57:34.487 回答
1

几年前我们遇到了这个问题。我现在找不到太多支持文档,但据我了解,Visual Studio 在 vtable 中对重载函数进行分组,即使它们是单独声明的。这导致我们的构建在 gcc 中工作正常,但在 Visual Studio 中崩溃。我相信我们最终只是删除了重载函数,因为我们没有找到解决方法。

于 2011-01-19T16:57:34.757 回答
0

它不一定是错误的索引——它们的 vtable 中可以有完全不同大小的条目。除非他们的 ABI 匹配,否则不能保证任何东西都是一样的。当他们的 ABI 匹配时,这是有保证的。

可能的 ABI 是 GCC 和 Intel 的 C++ 编译器使用的 IA64 abi,​​或 Microsoft 引入的 COM 互操作。

于 2010-07-14T10:08:29.577 回答