C++在函数模板中传递函数指针

标签 c++ templates visual-c++ x86 inline-assembly

我试图在模板中传递一个函数指针,然后在 asm 代码中使用它:

template <auto T>
_declspec(naked) void Test()
{
    __asm
    {
        lea eax, T
        jmp [eax]
    }
}

int main()
{
    Test<MessageBoxA>();
    Test<Sleep>();
}

我知道 naked 函数在执行时会崩溃,但我简化了代码以仅显示我想要实现的目标。

这段代码的问题是,一旦编译,如果你在反汇编器中查看汇编代码,它会是这样的:

lea eax, 0
jmp [eax]

它在 eax 中存储 0。相反,它应该将 MessageBoxA 地址(和 Sleep 在另一个函数中)存储在 eax 中。

我不知道是我做错了什么还是编译器出错了。

最佳答案

我不是汇编专家,但创建一个设置为非类型模板参数值的 static constexpr void* 似乎可以解决问题:

template <auto T>
__declspec(naked) void Test()
{
    static constexpr void* fptr = T;
    
    __asm 
    {
        lea eax, fptr
        jmp [eax]
    }
}

const void sleep()
{
}

int main()
{
    Test<(&sleep)>();
    return 0;
}

生成

lea     eax, OFFSET void * `void Test<&void sleep(void)>(void)'::`2'::fptr
jmp     SHORT DWORD PTR [eax]

这个例子可以在编译器资源管理器上运行:https://godbolt.org/z/f1d7daa49

关于C++在函数模板中传递函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71867090/

相关文章:

c++ - Qt 和 C++ : Array of function pointers with different return and parameter types

c++ - 避免使用模板函数的 if-else 语句

c++ - 模板内部的非常量非类型表达式

c++ - 接受 std::vector<T> 或 std::array<T> 的模板类

c++ - RegisterWaitForSingleObjectEx() 和几个 SetEvent()

c++ - 如何从 C++ 代码暂停 FFmpeg?

c++ - 自动对比度和亮度(用于 OCR)

c++ - QTreeWidgetItem 可编辑只允许输入数字

c++ - 为什么我必须声明一个静态 vector ?

visual-studio-2010 - Visual Studio 2010、QT 和智能感知/突出显示错误