简体   繁体   English

非静态成员函数的无效使用 - 类成员函数调用另一个类成员函数

[英]Invalid use of non-static member function - Class Member Function Calling Another Class Member Function

I keep getting this message when I try to compile:当我尝试编译时,我不断收到此消息:

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

Here is my task.c++ function:这是我的 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);
}

And here is my task.h:这是我的 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

Is this something wrong with calling this->OtherMain() inside this->createTask() ?this->createTask()调用this->OtherMain()有什么问题吗?

void(*task_main)() is expecting a pointer to a function. void(*task_main)()需要一个指向函数的指针。 You attempt to feed it void otherMain();你试图喂它void otherMain(); which is a class method and has a hidden this parameter.这是一个类方法并且有一个隐藏的this参数。

This stuff gets a little whacky.这东西变得有点古怪。 Here is a great write-up on some of the badness and how to avoid it.这是一篇关于一些坏处以及如何避免它的好文章。

You're going to have to do a bit of a rethink on how you do this.你将不得不重新思考如何做到这一点。 You can use a static void task_runner(void * userparam) method (no this ) and a user parameter that can be cast by the static method to provide a TaskManager on which you can invoke otherMain .您可以使用static void task_runner(void * userparam)方法(没有this )和可以由静态方法转换的用户参数来提供一个TaskManager ,您可以在其上调用otherMain You can turn void(*task_main)() into void(TaskManager::*task_main)() and you'll still have to provide a TaskManager to invoke the method pointer on.您可以将void(*task_main)()转换为void(TaskManager::*task_main)()并且您仍然必须提供一个TaskManager来调用方法指针。

It's a really nasty business, but can I interest you in exploring std::bind instead?这是一项非常糟糕的业务,但我可以让您对探索std::bind感兴趣吗?

Edit编辑

Task runner is something along the lines of this:任务运行器是这样的:

class taskRunner
{
public:
    virtual execute() = 0;
    static void task_runner(void * userparam)
    {
        taskRunner* task = (taskRunner*)userparam;
        task->execute();
    }
};

Downsides are everything you try to run MUST be a class that inherits taskRunner and implements execute and something must keep track of userparam .缺点是您尝试运行的所有内容都必须是一个继承taskRunner并实现execute的类,并且必须跟踪userparam Non trivial effort is involved, but what the hell.涉及非平凡的努力,但到底是什么。 Looks like you're writing yourself an OS.看起来您正在为自己编写操作系统。 Non trivial effort all-around.全方位的非平凡努力。

Probably better for you it to push the abstraction up one level and only accept free functions and static methods.将抽象提升一级并且只接受自由函数和静态方法可能对您更好。 Let the function being run sort out whether it's a class or not.让正在运行的函数弄清楚它是否是一个类。

This means that otherMain cannot be a member of TaskManager unless it's static and this will require a re-write of TaskManager to allow cross-cutting behaviour like a task's ability to sleep, yield its timeslice, and other OS goodies to be called without knowing the internals of TaskManager .这意味着otherMain不能是TaskManager的成员,除非它是静态的,这将需要重新编写TaskManager以允许横切行为,例如任务的睡眠能力、产生其时间片和其他操作系统好东西在不知道TaskManager内部结构。

otherMain could just be otherMain可能只是

void otherMain()
{
    printf("Hello multitasking world!"); 
    yield(); // a free function that calls into the system's TaskManager to preempt
}

The second parameter to createTask() is a: createTask()的第二个参数是:

 void(*task_main)()

This is a pointer to a function that returns void .这是一个指向返回void的函数的指针。

You are passing a:您正在通过:

 this->otherMain

otherMain is not a function that returns void . otherMain不是返回void的函数。 It is a class member that returns void .它是一个返回void的类成员。 A class member is not exactly the same as a function.类成员与函数并不完全相同。

The correct parameter type for createTask , to match a class method that returns void would be:与返回 void 的类方法匹配的createTask的正确参数类型是:

void  (TaskManager::*task_main)()

and the otherMain class method can be passed as simply:otherMain类方法可以简单地传递:

&TaskManager::otherMain

This would solve the immediate problem of the compilation error for this function call.这将解决此函数调用的编译错误的直接问题。

However, you will likely now have a new, different problem.但是,您现在可能会遇到一个新的、不同的问题。 Your existing code attempts to stuff the function pointer into something that resembles a CPU register.您现有的代码尝试将函数指针填充到类似于 CPU 寄存器的内容中。

Well, you don't have a function pointer any more.好吧,您不再有函数指针了。 You now have a class method pointer.您现在有一个类方法指针。 Whether or not the existing code will work, as is, depends on your C++ implementation.现有代码能否正常工作取决于您的 C++ 实现。 Probably not, but that would be a different question.可能不是,但这将是一个不同的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将非静态成员 function 传递给另一个 class 的成员 function - Pass non-static member function to member function of another class 非静态成员函数的无效使用在类模板的成员函数的实例化中? - Invalid use of non-static member function In instantiation of member function of a class template? 无效使用非静态成员函数 - invalid use of non-static member function How can I call a non-static member function of a class from a static member function of another class? - How can I call a non-static member function of a class from a static member function of another class? 如何设置(* sa_handler)(int)指向属于类成员的函数的指针? (无效使用非静态成员函数) - How to set (*sa_handler)(int) pointer to function which is member of a class? (invalid use of non-static member function) 将ino sketch 转换为C++ 类,非静态成员函数的使用无效 - Convert ino sketch to C++ class, invalid use of non-static member function 类的非静态成员函数的函数指针 - Function pointer of a non-static member function of a class 类静态函数中变量的非静态成员引用 - A non-static member reference of a variable inside a class' static function 无效使用非静态成员函数c ++ - Invalid use of non-static member function c++ boost :: thread无效使用非静态成员函数 - boost::thread invalid use of a non-static member function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM