嵌入式 C 中函数指针的用例是什么?为什么在回调函数中使用它?为什么我们不能使用正常的函数调用?我们不能使用正常的函数调用吗?
我无法理解函数指针的用例
函数指针是指向已加载到内存中的可执行代码的指针。函数指针可以指向模块内部或外部的代码。函数指针并不关心。
当 scribed 模块未与 calling 模块链接在一起时,calling 模块的地址在编译+链接时和运行时都不为被调用函数所知。
我们以Windows(具体来说是win32 API)为例:
一开始,被调用的函数(Windows)不知道“回调代码”(在您的应用程序中)在哪里。请注意,在 Windows 中,“控制程序”是您的应用程序;它调用win32.dll中的函数;但有时 win32.dll 需要将处理委托给应用程序,它需要 给您回电。
为了使 used 函数(win32.dll)之外的代码可用(即可寻址),需要告知该代码的地址。在回调的情况下,最简单的解决方案是calling应用程序将指向其自身代码的指针(更具体地说,其内部函数之一,实际的callback函数)传递给called函数参数之一(或作为参数传递的结构体字段)。
在著名的Windows WNDPROC回调函数中https://en.wikipedia.org/wiki/WindowProc它是application首先调用Windows,但是Windows想要回调你来处理Windows事件消息(鼠标点击、按下按钮、选择菜单项等等),因为处理这些事件是 application 的职责(毕竟应用程序知道如何处理这些事件)。因此,Windows 需要知道 WindowProc 的地址,并且实际上应用程序已经在
RegisterClass
win32 函数中传递了指向该函数的指针。 RegisterClassA(或 W)函数采用一个参数,即 WNDCLASSA 结构(应用程序需要填写该结构),并且 - 瞧,该结构中的第二个成员是未来对象的地址(= 指向的指针) -应用程序的回调窗口事件处理程序 WndProc。
typedef struct tagWNDCLASSA {
UINT style;
WNDPROC lpfnWndProc; <----- The Callback Window Function
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASSA, *PWNDCLASSA, *NPWNDCLASSA, *LPWNDCLASSA;
Windows“绕道”了窗口类(顺便说一句,这与面向对象的类无关;窗口类是相同类型(以及相同处理要求,即相同处理要求)的窗口使用的一组通用参数。相同的 WndProc),例如在编辑器中打开多个文件)。当您实际使用
CreateWindow
调用创建窗口时,您将窗口类传递给它,因此 Windows 从那里知道适当的 WndProc Windows 事件处理函数。
回调是一种非常优雅的方法。也许可以考虑其他方法,例如将应用程序实现为 DLL,然后通过 DLL 函数注册应用程序函数,但这不会让事情变得更简单,恕我直言。
希望这有帮助。