use*_*087 1 c++ gcc calling-convention visual-c++
我有一个程序生成与MSVC动态加载DLL.dll提供从主程序调用的函数.如果两者都使用MSVC或gcc构建,一切都很好,但是当我编译例如main与MSVC和dll与gcc的东西是错误的.
# ifdef __GNUC__
# define CDECL __attribute__ ((__cdecl__))
# else
# define CDECL __cdecl
# endif
struct EXP result {
uint32_t code;
};
#define SUCCESS result{0};
virtual result CDECL foo(char const* const*& target) const {
target = (char const* const*)0xAFFE;
return SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
问题是,在调用目标为零而不是0xAFFE之后.主程序使用__cdecl
调用约定编译.结构被打包(没有对齐),但我也尝试对齐不同的大小(1,2,4,8,16).我也尝试使用__declspec/__atribute__(dllexport)
两种变体的不同组合.
如果我查看汇编代码,有两个很大的区别:
; MSVC | gcc
;===============================|================================
; before calling |
;-------------------------------|--------------------------------
| sub dword ptr [esp+4],8
|
; foo(); |
;-------------------------------|--------------------------------
push ebp | push ebp
mov ebp,esp | mov ebp,esp
mov eax,dword ptr [target] |
mov dword ptr [eax],0AFFEh |
mov eax,dword ptr [ebp+0Ch] | mov eax,dword ptr [ebp+0Ch]
mov dword ptr [eax],0 | mov dword ptr [eax],0AFFEh
| mov eax,0
pop ebp | pop ebp
ret | ret
Run Code Online (Sandbox Code Playgroud)
即使我在两个编译器上使用相同的调用约定,为什么会这样?我该如何解决?
在这种情况下,调用约定毫无意义.问题是像vtable布局这样的东西.MSVC ABI和Itanium对很多事情都持不同意见.除非明确支持,否则无法编译C++接口并在编译器之间进行混合和匹配.如果设置正确的设置,Clang和G ++应该是可互操作的,并且Clang和MSVC可以互操作,具体取决于您使用的确切功能.
一般来说,不要混用和匹配C++接口的C++编译器.它不会起作用.
归档时间: |
|
查看次数: |
2786 次 |
最近记录: |