gpt4 book ai didi

c++ - 是否可以用汇编语言编写 dllexport(然后是 dllimport)函数?

转载 作者:太空狗 更新时间:2023-10-29 23:02:14 24 4
gpt4 key购买 nike

我有一个大型 C++ 项目,其中包含几个模块 - 所有模块都被编译为动态库。我面向多个平台,包括 Windows、Linux 和 MacOSX。

分析测试揭示了一些关键点,在这些点上我能够获得巨大的性能提升,例如:哈希计算、一些 vector 操作等。我使用 SSE/MMX 在汇编中实现了这个功能。

一切都很好,直到我切换回 Visual C++ 中的 x64 目标,其中不允许内联汇编。我卡住了。此外,这些功能也用于其他模块。

基本上,我想要实现的是实现一些函数,这些函数驻留在程序集中的 DLL 中。我试过这个:

API.h

extern "C" void DLL_API __stdcall sample_fun(/*args*/);

API.asm

sample_fun PROC public ;args
.....
sample_fun ENDP

这显然是行不通的,因为名称修改。

我也试过这个:

API.h

void DLL_API sample_fun(/*args*/);

API.cpp

extern "C" __stdcall sample_fun_impl(/*args*/).

void DLL_API sample_fun(/*args*/)
{
return sample_fun_impl(/*args*/);
}

API.asm

sample_fun_impl PROC public ;args
.....
sample_fun_impl ENDP

在这种情况下,我仍然收到有关未解析的外部符号 (sample_fun_impl) 的链接器错误,这很奇怪,因为它实际上是一个私有(private)函数,只能从 DLL 中调用。

有没有可能做我想做的事?

最佳答案

那么,问题就解决了。这是我想要的一些解释的最小示例:

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 的函数由链接器使用其名称前加下划线进行搜索。我制作了有问题的 DLL 的 dumpbin 并且它就在那里 - 但确实在开头有一个下划线!所以我保留了它的声明,并将其名称从 roundup_pow2_32_impl 更改为 _roundup_pow2_32_impl,同时,我添加了 MODEL FLAT, C

3) 我在 .asm 文件中使用了 IFDEF/IFNDEF。但我假设,所有对 cl 可见的定义对 ml/ml64 也是可见的。错误的。只有在手动添加所需的常量后,一切才开始工作(.asm 文件属性 -> Microsoft Macro Assembler -> General -> Preprocessor Definitions)。

我想在尝试了许多不同的解决方案之后,一切都变成了一个大困惑。干净的设置完美运行:

main.cpp

#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

非常感谢bogdan!如果没有他关于在 x64 上调用约定说明符的提示,我不会解决这个问题。

关于c++ - 是否可以用汇编语言编写 dllexport(然后是 dllimport)函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29265736/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com