void main_loop(const CMsg); //прототип функции
typedef void (*HPROC)(const CMsg); //тип-функция
bool MessageSubscribe(HPROC hCallback, uint32_t uEvent); //прототип функции, в которую нужно передать указатель функции.
调用 MessageSubscribe 时,hCallback 传递的是 main_loop 函数代码的一部分,而不是指针。将 HPROC 更改为 void* 不会改变任何内容。使用 & 符号 (&main_loop) 根本不会影响任何事情。如果 main_loop 位于单独的文件中,则会出现问题。
IDT表中描述的“骑士的举动”,而不是指针,而是输入了一部分代码。错误在哪里?不能应用。
我在启用调试的情况下检查 VirtualBox 中的工作。并且调用调用获取的不是函数的地址,而是函数代码的开头。
变量中确认的内部输出。我特别介绍了调试行(kprint 是 printf 的类似物,不支持格式化,第二个参数是换行):
kprint((HANDLE)*main_loop, true);
kprint((HANDLE)main_loop, true);
kprint((HANDLE)&main_loop, true);
MessageSubscribe(&main_loop, EV_SYS);
MessageSubscribe(&main_loop, EV_KBD);
0x400000...0x4FFFFF 内的普通代码地址
as的输出:kmmain.oS和main_loop.oS

默认情况下,编译 64 位代码(AMD64/EM64T)时,启用 PIE 参数,即相对于 RIP 命令寄存器取数据。
当一个函数被调用时,它的地址被替换,当作为数据传递时,一个指向数据的相对指针被使用,而不是函数,因为数据不应该被作为函数调用。
解决方案:为编译器指定 -fno-pie 选项。