【问题标题】:ESP was not properly saved across a function call when using function pointers使用函数指针时,ESP 未在函数调用中正确保存
【发布时间】:2018-11-28 11:10:09
【问题描述】:

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

运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是用一个调用约定声明的函数和一个用不同调用约定声明的函数指针调用的结果。

我的代码是:

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);
    }
}

如果有人可以提供帮助,将不胜感激。

【问题讨论】:

  • 指向成员函数的指针与指向函数的普通指针不同。您的代码有一些非常未定义的行为。
  • 您将需要 std::function 和一个 lambda 或 std::bind 来完成这一切,因为您使用的是来自不同类的函数。
  • 扩展@StoryTeller 的评论,指向成员函数的指针需要调用一个object。如果没有对象,就不能调用函数。
  • meta.stackexchange.com/questions/66377/what-is-the-xy-problem "我正在尝试创建一个程序,将成员函数的函数指针保存到数组中" ...这就是您认为的解决方案,但问题是什么?为什么你认为首先需要函数指针?
  • @StoryTeller 和@Some 程序员老兄:我将 FuncTest 更改为静态,将 ffp 更改为 void (*ffp)(byte*) = &amp;FuncTest;,并且成功了。谢谢!

标签: c++ function-pointers


【解决方案1】:

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

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

ffp 的类型本质上是(尽管不完全是由于不同的调用约定)void (fTest*, byte*),它与 func_pointer 的类型不匹配。

解决方案是使用 std::functionstd::bind 或 lambdas 来转换函数签名。例如:

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

【讨论】:

  • 感谢您的回答,但我发现了我的错误。该函数应该是静态的。话虽如此,如果我决定将来使用成员函数,我会考虑你的回答。
猜你喜欢
  • 2012-01-30
  • 1970-01-01
  • 2013-11-30
  • 2013-07-03
  • 2011-09-17
  • 2012-04-06
  • 2021-06-21
  • 2020-05-04
  • 2015-09-06
相关资源
最近更新 更多