所以,问题已经解决了。这是我想要的一些解释的最小示例:
Asx.h
namespace Asx
{
#if ASX_PLATFORM_IS64BIT //This is resolved using 'ifdef _M_X64'
extern ASX_DLL_API ULONGLONG roundup_pow2_64(ULONGLONG value);
#else
extern ASX_DLL_API DWORD roundup_pow2_32(DWORD value);
#endif
}
asx.cpp
#include "Asx.h"
#if ASX_PLATFORM_IS64BIT
extern "C" ULONGLONG __cdecl roundup_pow2_64_impl(ULONGLONG value);
#else
extern "C" DWORD __cdecl roundup_pow2_32_impl(DWORD value);
#endif
namespace Asx
{
#if ASX_PLATFORM_IS64BIT
ULONGLONG roundup_pow2_64(ULONGLONG value)
{
return roundup_pow2_64_impl(value);
}
#else
DWORD roundup_pow2_32(DWORD value)
{
return roundup_pow2_32_impl(value);
}
#endif
}
Asx_asm_impl.asm
IFNDEF ASX_PLATFORM_IS64BIT
.686P
.MODEL FLAT, C
.XMM
ENDIF
.CODE
IFDEF ASX_PLATFORM_IS64BIT
roundup_pow2_64_impl PROC public, value:QWORD
//Implementation
roundup_pow2_64_impl ENDP
ELSE
roundup_pow2_32_impl PROC public, value:DWORD
//Implementation
roundup_pow2_32_impl ENDP
ENDIF
END
什么问题?
1)我没有考虑到,调用约定在 x64 中的处理方式不同,但是意外地这并没有引起任何问题。
2)在某些时候,我注意到,标记的函数__cdecl
由链接器搜索,使用它们的名称加上下划线。我制作dumpbin
了有问题的 DLL,它就在那里——但确实在开头有一个下划线!所以我保留了它的声明,并将它的名称从 更改为roundup_pow2_32_impl
同时_roundup_pow2_32_impl
,我添加了MODEL FLAT, C
.
3) 我在文件中使用了 IFDEF/IFNDEF .asm
。但我假设,所有可见的定义对/cl
也是可见的。错误的。只有在手动添加所需的常量之后,一切才开始工作(文件属性 -> Microsoft 宏汇编器 -> 常规 -> 预处理器定义)。ml
ml64
.asm
我想在尝试了许多不同的解决方案之后,一切都变成了一个大混乱。干净的设置工作完美:
主文件
#include "../Asx/Header.h"
int main(int argc, char** argv)
{
#if ASX_PLATFORM_IS64BIT
ULONGLONG v = Asx::roundup_pow2_64(4000);
#else
DWORD v = Asx::roundup_pow2_32(4000);
#endif
return 0;
}
结果在 Win32 和 x64:4096
中。
非常感谢博格丹!如果没有他关于在 x64 上调用约定说明符的提示,我不会解决这个问题。