vtable 中重载方法的顺序(在 win32 上)
vtable 中重载方法的顺序在 win32 编译器中始终相同吗?
问题: 我有“接口”(没有数据成员的纯虚拟类)。它们可以通过来自不同编译器的指针来使用(客户端通过调用标准 c dll 工厂方法来获取指针)。除了一种方法外,这在不同的编译器(例如用 borland 编写的客户端,用 Visual C++ 编写的接口 dll)中都可以正常工作。 该方法被重载,具有相同的返回值但不同的参数。该方法有 4 个版本。对此方法的相同调用会返回不同的结果,具体取决于编译客户端的编译器。快速浏览一下汇编程序代码,我发现 vtable 中似乎有不同的偏移量(我不太擅长阅读汇编程序)。
现在我不知道 - 我是否找到了原因,或者 borland 只是处理与 Visual Studio 不同的 vtable,一切都是正确的,我必须在其他地方搜索。
最好的问候并感谢您的回答
托比亚斯
is the order of overloaded methods in the vtable always the same across win32 compilers?
Problem:
I have "interfaces" (pure virtual classes with no data members). They can be used via pointer from different compilers (the client gets the pointer by calling a standard c dll factory method). This works fine across different compiler (e.g. client written with borland, interface dll written with Visual C++) except for one method.
This method is overloaded with the same return value but different parameter. There are 4 versions of this method. The same call to this method returns different results depending on the compiler that compiled the client. A quick look a the assembler code showed me that there seems to be a different offset into the vtable (I'm not really good at reading assembler).
Now I don't know - did I find the cause or is borland just handling the vtable different to visual studio and everything is correct and I have to search elsewhere.
best regards and thank you for your answers
Tobias
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有两个可能的原因:客户端编译器选择的重载与您期望的不同,或者不同的编译器将重载放入不同的 vtable 条目中。
您传递/期望什么参数?重载解析可能是问题所在吗?
如果是 vtable 条目,那么您可以尝试重命名重载。
您是否尝试过在声明接口时使用目标编译器上可用的任何 COM 机制 --- 例如,在 MSVC 中使用
interface
关键字,并为您的接口类提供 GUID。 COM 接口应该按照声明的顺序在 vtable 中具有函数,因此如果它们共享相同的标头,那么这在编译器之间是常见的。There are two possible causes: either the client compiler is choosing a different overload than you expect, or the different compilers are putting the overloads in different vtable entries.
What parameters are you passing/expecting? Could overload resolution be the problem?
If it's the vtable entries then you could try renaming the overloads.
Have you tried using whatever COM mechanism is available on your target compilers when declaring the interface --- e.g. using the
interface
keyword in MSVC, and giving your interface class a GUID. COM interfaces are supposed to have the functions in the vtable in the order declared, which is therefore common between compilers if they share the same header.vtable 中函数的顺序是 ABI 涵盖的内容之一。不幸的是,ABI 不是 C++ 标准的一部分,因此不同的编译器使用不同的 ABI 是很常见的。
The order of functions in the vtable is one of the things covered by the ABI. Unfortunately, the ABI is not part of the C++ standard so it is quite common for different compilers do use different ABIs.
几年前我们就遇到过这个问题。我现在找不到太多支持文档,但据我了解,Visual Studio 会在 vtable 中对重载函数进行分组,即使它们是单独声明的。这导致我们的构建在 gcc 中运行良好,但在 Visual Studio 中崩溃。我相信我们最终只是删除了重载的函数,因为我们没有找到解决方法。
We ran into this problem a few years ago. I can't find much supporting documentation for it now, but it is my understanding that visual studio groups overloaded functions in the vtable even if they are declared separately. This was causing our build to work fine in gcc, but crash in visual studio. I believe we eventually just removed the overloaded functions, as we didn't find a way around it.
不一定是索引出了问题——它们的 vtable 中可以有完全不同大小的条目。除非他们的 ABI 匹配,否则不能保证一切都是相同的。当他们的 ABI 确实匹配时,这是有保证的。
可能的 ABI 是 GCC 和 Intel 的 C++ 编译器使用的 IA64 abi,或者 Microsoft 引入的 COM 互操作。
It needn't be the index that's wrong - they can have completely different size entries in their vtables. Unless their ABI matches, there's no guarantee anything is the same. When their ABI does match, it's guaranteed.
Possible ABI's are the IA64 abi that's used by GCC and Intel's C++ compiler, or the COM interop that Microsoft introduced.