gpt4 book ai didi

c++ - 在用 C++ 编写 win32 api 包装器时,如何将此指针传递给静态函数

转载 作者:行者123 更新时间:2023-11-30 01:33:02 26 4
gpt4 key购买 nike

我想将函数对象转换为函数。

我写了这段代码,但它不起作用。

#include <iostream>

typedef int (*int_to_int)(int);

struct adder {
int n_;
adder (int n) : n_(n) {}
int operator() (int x) { return x + n_; }
operator int_to_int () {
return this->*&adder::operator();
}
};

int main(void) {
adder add_two(2);
int_to_int add_fn = add_two;
std::cout << add_two(3) << std::endl; // expect 5
std::cout << add_fn(3) << std::endl; // expect 5
add_fn = adder(5);
std::cout << add_fn(3) << std::endl; // expect 8
return 0;
}

我收到来自 g++ 的消息,说 invalid use of non-static member function

如何获取指向实例成员函数的指针?

编辑:我原来的问题是关于 Win32 API。

我在学校被迫使用旧的 Win32 API 编写 Windows 程序。但我不想像文本上的一些示例代码那样编写可怕的 switch 语句。然后,我决定用 C++ 编写包装器。

我想把窗口类写成...

class Window {
public:
LRESULT update (HWND, UINT, WPARAM, LPARAM);
void run();
// below methods are called by update()
virtual void onclick(int, int);
virtual void ondraw(); // ... and more methods
};

并且我愿意通过派生此类并重载一些方法来编写我的应用程序类。

最后,我真正的问题是如何在 C++ 中做到这一点。

 // on initializing my window object,
// I must register window class with callback which is
// not a C++ function object.
// I try to explain what I want to do with psudocode mixing C++ and javascript.
WNDCLASS wndclass;
Window *self = this;
wndclass.lpfnWndProc = function () {
return self.update.apply(self, argunemts);
};

换句话说,我必须将闭包变成函数指针。我不知道该怎么做,但我不敢相信这不能用 C++ 实现。

编辑:这个问题的原标题是如何获取实例成员函数的指针。但是这个标题和我的问题并没有充分说明我的实际问题。对早期的回答者和 litb 表示抱歉,感谢您的建议和非常有用的答案!

最佳答案

更新:您告诉我们您想要什么。我在 SO 上发现了这个问题:Best method for storing this pointer for use in WndProc .我不是 Windows 程序员,但 Adam Rosenfield 的人似乎在使用 SetWindowLongPtr 和 GetWindowLongPtr 方面是正确的。所以,你可以这样使用它:

LRESULT CALLBACK my_callback(HWND hwnd, UINT ui, WPARAM wp, LPARAM lp) {
Window * self = reinterpret_cast<Window*>(
GetWindowLongPtr(hwnd, 0));
return self->update(hwnd, ui, wp, lp); // handle it.
}

将该函数注册为 wnd-proc 并使用 SetWindowLongPtr 存储 Window 对象的 this 指针。在 WNDCLASSEX 结构中,有一个 cbWndExtra 字段,您可以将 sizeof(Window*) 分配给它,它足以存储仅包含 this指针。然后你可以调用

SetWindowLongPtr(my_hwnd, 0, reinterpret_cast<LONG_PTR>(this));

将 this 指针放入该区域。然后像上面那样接收并委托(delegate)给真正的成员函数。理论上您也可以使用静态成员函数。但你必须要小心。从 C 代码调用静态成员函数可能会导致错误,因为 C 代码和 C++ 代码之间的调用约定可能不同。对于 Windows,这可能不是问题 - 我不知道。所以最好另外检查一下自己。


你尝试的东西是无效的。您尝试返回一个指向函数调用运算符的指针,但调用时没有提供任何对象,除此之外您的转换运算符类型错误。转换运算符返回的类型是函数指针类型,不是成员函数指针类型。最接近的是使用正确的类型:

struct adder;
typedef int (adder::*int_to_int)(int);

struct adder {
int n_;
adder (int n) : n_(n) {}
int operator() (int x) { return x + n_; }
operator int_to_int () {
return &adder::operator();
}
};

现在,您的转换运算符甚至都不在考虑之列,因为它必须这样调用:

adder a(10); cout << (a.*(int_to_int)a)(2); // expected: 12

然后手动像这样:

// note, we just get the member function pointer using the conversion operator.
// Nothing is related to the actual temporary adder object.
int_to_int i = adder(5);
cout << (adder(10).*i)(2); // expected: 12

通常的函数调用语法无法解决这个问题。简而言之,您尝试的是不可能的。

我认为另一个问题是,您到底为什么要这样做?我认为当我们知道最初的问题是什么时,我们可以更好地帮助您。如果你想让它看起来和工作起来像一个函数调用,你根本不需要任何转换运算符:

struct adder {
int n_;
adder (int n) : n_(n) {}
int operator() (int x) { return x + n_; }
};

adder a(10); cout << a(2); // expected: 12

关于c++ - 在用 C++ 编写 win32 api 包装器时,如何将此指针传递给静态函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/412183/

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