非静态成员函数的使用无效 - Class 成员函数调用另一个 Class 成员函数
Invalid use of non-static member function - Class Member Function Calling Another Class Member Function
我在尝试编译时不断收到此消息:
task.c++:54:102: error: invalid use of non-static member function
this->createTask(&otherTask, this->otherMain, mainTask.regs.eflags, (uint32_t*)mainTask.regs.cr3);
这是我的 task.c++ 函数:
#include "task.h"
static task_q *runningTask;
static task_q mainTask;
static task_q otherTask;
static PhyiscalMemoryManager *pmm_task;
static Heap *heap_task;
extern void switch_task_a();
TaskManager::TaskManager(Heap *heap)
{
heap_task = heap;
}
TaskManager::~TaskManager()
{}
Task::Task()
{}
Task::~Task()
{}
void TaskManager::otherMain()
{
printf("Hello multitasking world!"); // Not implemented here...
preempt();
}
void TaskManager::createTask(task_q* task, void(*task_main)(), uint32_t flags, uint32_t* pageDir)
{
task->regs.ebx = 0;
task->regs.ecx = 0;
task->regs.edx = 0;
task->regs.esi = 0;
task->regs.edi = 0;
task->regs.eflags = flags;
task->regs.eip = (uint32_t) task_main;
task->regs.cr3 = (uint32_t) pageDir;
task->regs.esp = (uint32_t) (heap_task->k_malloc(TASK_STACK_SIZE)) + 0x1000; // Not implemented here
task->next = 0;
}
void TaskManager::init_tasking()
{
// Get EFLAGS and CR3
__asm __volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(mainTask.regs.cr3)::"%eax");
__asm __volatile("pushfl; movl (%%esp), %%eax; movl %%eax, %0; popfl;":"=m"(mainTask.regs.eflags)::"%eax");
this->createTask(&otherTask, this->otherMain, mainTask.regs.eflags, (uint32_t*)mainTask.regs.cr3);
mainTask.next = &otherTask;
otherTask.next = &mainTask;
runningTask = &mainTask;
}
void TaskManager::switchTask(Registers *old, Registers *new_)
{
switch_task_a();
}
void TaskManager::preempt()
{
task_q *last = runningTask;
runningTask = runningTask->next;
switchTask(&last->regs, &runningTask->regs);
}
这是我的 task.h:
#ifndef _TASK_H_
#define _TASK_H_ 1
#include <stdarg.h>
#include <stdint.h>
#include "gdt.h"
#include "stdio.h"
#include "heap.h"
#include "pmm.h"
#define TASK_STACK_SIZE 0x2000
typedef struct {
uint32_t eax, ebx, ecx, edx, esi, edi,
esp, ebp, eip, eflags, cr3;
} Registers;
typedef struct task_q {
Registers regs;
struct task_q *next;
} task_q;
class Task
{
friend class TaskManager;
public:
Task();
~Task();
private:
};
class TaskManager
{
public:
TaskManager(Heap *heap);
~TaskManager();
void init_tasking();
static void createTask(task_q* task, void(*task_main)(), uint32_t flags, uint32_t* pageDir);
void preempt();
private:
void switchTask(Registers *old, Registers *new_);
void otherMain();
};
#endif
在 this->createTask()
中调用 this->OtherMain()
有问题吗?
void(*task_main)()
需要一个指向函数的指针。您尝试向它提供 void otherMain();
,这是一个 class 方法并且有一个隐藏的 this
参数。
这东西有点古怪。 Here is a great write-up on some of the badness and how to avoid it.
您将不得不重新考虑如何执行此操作。您可以使用 static void task_runner(void * userparam)
方法(无 this
)和可由静态方法强制转换的用户参数来提供可以调用 otherMain
的 TaskManager
。您可以将 void(*task_main)()
转换为 void(TaskManager::*task_main)()
,您仍然需要提供一个 TaskManager
来调用方法指针。
这真是一件令人讨厌的事情,but can I interest you in exploring std::bind
instead?
编辑
任务 运行ner 是这样的:
class taskRunner
{
public:
virtual execute() = 0;
static void task_runner(void * userparam)
{
taskRunner* task = (taskRunner*)userparam;
task->execute();
}
};
缺点是您尝试做的所有事情 运行 必须是继承 taskRunner
并实现 execute
的 class,并且必须跟踪 userparam
。涉及非平凡的努力,但到底是什么。看起来你正在给自己写一个 OS。全方位的不平凡的努力。
将抽象提升一级并只接受自由函数和静态方法可能对您更好。让函数运行判断它是否是class。
这意味着 otherMain
不能成为 TaskManager
的成员,除非它是静态的,这将需要重写 TaskManager
以允许像任务能力这样的横切行为睡觉,产生它的时间片,以及在不知道 TaskManager
.
的内部结构的情况下调用其他 OS 好东西
otherMain
可能只是
void otherMain()
{
printf("Hello multitasking world!");
yield(); // a free function that calls into the system's TaskManager to preempt
}
createTask()
的第二个参数是:
void(*task_main)()
这是一个指向函数的指针 returns void
。
您正在传递:
this->otherMain
otherMain
不是 returns void
的函数。 returns void
是 class 成员。 class 成员与函数不完全相同。
createTask
的正确参数类型,以匹配 returns void 的 class 方法:
void (TaskManager::*task_main)()
和 otherMain
class 方法可以简单地传递:
&TaskManager::otherMain
这将解决此函数调用的编译错误的直接问题。
但是,您现在可能会遇到一个新的、不同的问题。您现有的代码试图将函数指针填充到类似于 CPU 寄存器的东西中。
好吧,你不再有函数指针了。您现在有一个 class 方法指针。现有代码是否可以正常工作取决于您的 C++ 实现。可能不是,但这将是一个不同的问题。
我在尝试编译时不断收到此消息:
task.c++:54:102: error: invalid use of non-static member function
this->createTask(&otherTask, this->otherMain, mainTask.regs.eflags, (uint32_t*)mainTask.regs.cr3);
这是我的 task.c++ 函数:
#include "task.h"
static task_q *runningTask;
static task_q mainTask;
static task_q otherTask;
static PhyiscalMemoryManager *pmm_task;
static Heap *heap_task;
extern void switch_task_a();
TaskManager::TaskManager(Heap *heap)
{
heap_task = heap;
}
TaskManager::~TaskManager()
{}
Task::Task()
{}
Task::~Task()
{}
void TaskManager::otherMain()
{
printf("Hello multitasking world!"); // Not implemented here...
preempt();
}
void TaskManager::createTask(task_q* task, void(*task_main)(), uint32_t flags, uint32_t* pageDir)
{
task->regs.ebx = 0;
task->regs.ecx = 0;
task->regs.edx = 0;
task->regs.esi = 0;
task->regs.edi = 0;
task->regs.eflags = flags;
task->regs.eip = (uint32_t) task_main;
task->regs.cr3 = (uint32_t) pageDir;
task->regs.esp = (uint32_t) (heap_task->k_malloc(TASK_STACK_SIZE)) + 0x1000; // Not implemented here
task->next = 0;
}
void TaskManager::init_tasking()
{
// Get EFLAGS and CR3
__asm __volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(mainTask.regs.cr3)::"%eax");
__asm __volatile("pushfl; movl (%%esp), %%eax; movl %%eax, %0; popfl;":"=m"(mainTask.regs.eflags)::"%eax");
this->createTask(&otherTask, this->otherMain, mainTask.regs.eflags, (uint32_t*)mainTask.regs.cr3);
mainTask.next = &otherTask;
otherTask.next = &mainTask;
runningTask = &mainTask;
}
void TaskManager::switchTask(Registers *old, Registers *new_)
{
switch_task_a();
}
void TaskManager::preempt()
{
task_q *last = runningTask;
runningTask = runningTask->next;
switchTask(&last->regs, &runningTask->regs);
}
这是我的 task.h:
#ifndef _TASK_H_
#define _TASK_H_ 1
#include <stdarg.h>
#include <stdint.h>
#include "gdt.h"
#include "stdio.h"
#include "heap.h"
#include "pmm.h"
#define TASK_STACK_SIZE 0x2000
typedef struct {
uint32_t eax, ebx, ecx, edx, esi, edi,
esp, ebp, eip, eflags, cr3;
} Registers;
typedef struct task_q {
Registers regs;
struct task_q *next;
} task_q;
class Task
{
friend class TaskManager;
public:
Task();
~Task();
private:
};
class TaskManager
{
public:
TaskManager(Heap *heap);
~TaskManager();
void init_tasking();
static void createTask(task_q* task, void(*task_main)(), uint32_t flags, uint32_t* pageDir);
void preempt();
private:
void switchTask(Registers *old, Registers *new_);
void otherMain();
};
#endif
在 this->createTask()
中调用 this->OtherMain()
有问题吗?
void(*task_main)()
需要一个指向函数的指针。您尝试向它提供 void otherMain();
,这是一个 class 方法并且有一个隐藏的 this
参数。
这东西有点古怪。 Here is a great write-up on some of the badness and how to avoid it.
您将不得不重新考虑如何执行此操作。您可以使用 static void task_runner(void * userparam)
方法(无 this
)和可由静态方法强制转换的用户参数来提供可以调用 otherMain
的 TaskManager
。您可以将 void(*task_main)()
转换为 void(TaskManager::*task_main)()
,您仍然需要提供一个 TaskManager
来调用方法指针。
这真是一件令人讨厌的事情,but can I interest you in exploring std::bind
instead?
编辑
任务 运行ner 是这样的:
class taskRunner
{
public:
virtual execute() = 0;
static void task_runner(void * userparam)
{
taskRunner* task = (taskRunner*)userparam;
task->execute();
}
};
缺点是您尝试做的所有事情 运行 必须是继承 taskRunner
并实现 execute
的 class,并且必须跟踪 userparam
。涉及非平凡的努力,但到底是什么。看起来你正在给自己写一个 OS。全方位的不平凡的努力。
将抽象提升一级并只接受自由函数和静态方法可能对您更好。让函数运行判断它是否是class。
这意味着 otherMain
不能成为 TaskManager
的成员,除非它是静态的,这将需要重写 TaskManager
以允许像任务能力这样的横切行为睡觉,产生它的时间片,以及在不知道 TaskManager
.
otherMain
可能只是
void otherMain()
{
printf("Hello multitasking world!");
yield(); // a free function that calls into the system's TaskManager to preempt
}
createTask()
的第二个参数是:
void(*task_main)()
这是一个指向函数的指针 returns void
。
您正在传递:
this->otherMain
otherMain
不是 returns void
的函数。 returns void
是 class 成员。 class 成员与函数不完全相同。
createTask
的正确参数类型,以匹配 returns void 的 class 方法:
void (TaskManager::*task_main)()
和 otherMain
class 方法可以简单地传递:
&TaskManager::otherMain
这将解决此函数调用的编译错误的直接问题。
但是,您现在可能会遇到一个新的、不同的问题。您现有的代码试图将函数指针填充到类似于 CPU 寄存器的东西中。
好吧,你不再有函数指针了。您现在有一个 class 方法指针。现有代码是否可以正常工作取决于您的 C++ 实现。可能不是,但这将是一个不同的问题。