c++ - 使用函数指针时,ESP 未在函数调用中正确保存

标签 c++ function-pointers

我正在尝试创建一个将成员函数的函数指针保存到数组的程序。然后程序从该数组中获取函数指针并调用该指针指向的函数。只要使用的成员函数没有任何参数,这就有效。当我给它参数时,Visual Studio 2017 中出现以下错误:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

我的代码是:

typedef uint8_t byte;

template<typename T>
class Test
{
public:
    void FuncTest(byte* data)
    {
        cout << (T)(0.0625f) << endl;
    }
};

typedef Test<float> fTest;
typedef Test<long long> lTest;

int main()
{
    byte data[1024];

    {
        void (fTest::*ffp)(byte*) = &fTest::FuncTest;
        //void (lTest::*lfp)(byte*) = &lTest::FuncTest;

        printf("%p\n", ffp);

        memcpy(&data[0], (int64*)&ffp, sizeof(int64));
    }

    {
        int64 pData;

        memcpy(&pData, &data[0], sizeof(int64));

        void(*func_pointer)(byte*) = (void(*) (byte*))(pData);

        printf("%p\n", pData);

        func_pointer(nullptr);
    }
}

如果有人能提供帮助,我们将不胜感激。

最佳答案

忽略数组中的存储,您的代码本质上是:

void (Test::*ffp)(byte*) = &fTest::FuncTest;
void* pData = (void*)ffp;
void(*func_pointer)(byte*) = (void(*) (byte*))(pData);
func_pointer(nullptr);

ffp 的类型本质上是(虽然不完全是由于不同的调用约定)void (fTest*, byte*)函数指针

对此的解决方案是将 std::functionstd::bind 或 lambda 一起使用以转换函数签名。例如:

std::vector<std::function<void(byte*)>> functions;
fTest test;
functions.push_back([=](byte* data){ test.FuncTest(data); });
functions.front()(nullptr);

关于c++ - 使用函数指针时,ESP 未在函数调用中正确保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50929216/

相关文章:

c++ - 在 Qml 代码中编辑 C++ QList<Object*> 模型的问题和一些 Qml 警告

C++函数指针

c - 函数指针相对于标志的优势

C++ 指向成员函数的指针作为模板默认参数

go - 比较 Go 中的函数值

c++ - 在构造函数初始化列表中初始化 stringstream 引用成员

c++ - 视觉 C++ :error C2664: 'GetModuleFileNameW' : cannot convert parameter 2 from 'char [260]' to 'LPWCH'

c++ - 一种直接根据掩码转位的方法

C++ int main (int argc, char *argv[]) - argv 是 c 风格数组吗?

c - 如何区分C中的函数指针是指向函数1还是函数2