无法将参数“2”的 'int (Scheduler::*)(int, void*)' 转换为 'int (*)(int, void*)' 到 'bool irq_InstallISR(int, int (*)(int, void*), void*)'
cannot convert 'int (Scheduler::*)(int, void*)' to 'int (*)(int, void*)' for argument '2' to 'bool irq_InstallISR(int, int (*)(int, void*), void*)'
我在irq header里有这个函数
/* irq.h */
bool irq_InstallISR(int irq, int (*isr)(int, void*), void* isr_data);
和一个class调度器
/* Scheduler.cpp */
using namespace x86Duino;
void Scheduler::init(){
...
irq_InstallISR(RTCIRQ, &Scheduler::timerrtc_isr_handler, isrname_rtc);
...
}
int Scheduler::timerrtc_isr_handler(int irq, void* data){
...
}
我遇到了这个错误
error: cannot convert 'int (x86Duino::Scheduler::*)(int, void*)' to 'int (*)(int, void*)' for argument '2' to 'bool irq_InstallISR(int, int (*)(int, void*), void*)'
我已经在初始化函数中尝试过了
using namespace std::placeholders;
irq_InstallISR(RTCIRQ, std::bind(&Scheduler::timerrtc_isr_handler, this, _1, _2), isrname_rtc);
但是我也遇到了类似的错误
error: cannot convert 'std::_Bind_helper<false, int (x86Duino::Scheduler::*)(int, void*), x86Duino::Scheduler*, const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type {aka std::_Bind<int (x86Duino::Scheduler::*(x86Duino::Scheduler*, std::_Placeholder<1>, std::_Placeholder<2>))(int, void*)>}' to 'int (*)(int, void*)' for argument '2' to 'bool irq_InstallISR(int, int (*)(int, void*), void*)'
请告诉我我做错了什么?
您没有包含 Scheduler::timerrtc_isr_handler 的声明,所以我的第一个猜测是您忘记将该方法声明为静态的?
即在 class 定义中,它应该看起来像:
class Scheduler
{
static int timerrtc_isr_handler(int irq, void* data);
};
irq_InstallISR采用全局函数。错误信息说它不能转换这个原型:
int (Scheduler::*)(int, void*)
里面是一个成员函数,要
int (*)(int, void*)
这是一个普通的 C 函数(或非成员函数,例如静态方法)。
/edit 我猜你想要类似这种模式的东西:
class Scheduler
{
public:
Scheduler()
{
irq_InstallISR(RTCIRQ, timerrtc_isr_handler, this);
}
~Scheduler()
{
// probably want to uninstall the callback here!
}
int isr_handler(int irq)
{
/// do you handling here
}
private:
static int timerrtc_isr_handler(int irq, void* data)
{
// cast user data to correct class type
Scheduler* sch = (Scheduler*)data;
assert(sch); // just in case we get null for some reason?
// thunk call to member function
return sch->isr_handler(irq);
}
};
/编辑 2
您不是在将方法声明为静态或 int 之间进行选择,而是在静态函数(即无权访问 'this')或成员函数(需要 'this').考虑以下因素:
struct Foo
{
void func1() { std::cout << "func1\n"; }
static void func2() { std::cout << "func2\n"; }
};
void bar()
{
// call the static method - does not require an object!
Foo::func2();
// to call func1, we ALWAYS need an object...
Foo obj;
obj.func1();
}
所以让我们更进一步。假设我编写了一个 C-API 库。 C 不支持 C++ classes,因此通常为了与基于 C++ class 的代码进行互操作,您通常会求助于相当常见的用户数据模式。所以我将尝试将其简化为最简单的示例....
/// MyLib.h
// I want to call this method, and it will inturn call any
// callback functions registered with the system.
void callMyRegisteredFunction();
// the type of function I want to call in the previous method
// The C++ way of doing this is to say :
//
// someObject->func();
//
// However in C, without classes, the way you'd call it would be:
//
// func(someObject);
//
// so the second pointer here is the object to call it on.
typedef void (CallbackFunc*)(void*);
// register a callback function, and an associated user-defined object
void registerFunc(CallbackFunc funcPtr, void* userData);
// reset the internal callback
void unregisterFunc();
/// MyLib.cpp
#include "MyLib.h"
// the currently registered callback function
CallbackFunc g_func = NULL;
// the 'object' it is registered against. From 'C' we don't know that
// what type of object this is, we just know it's address.
void* g_userData = NULL;
void registerFunc(CallbackFunc funcPtr, void* userData)
{
g_func = funcPtr;
g_userData = userData;
}
void unregisterFunc()
{
g_func = NULL;
g_userData = NULL;
}
void callMyRegisteredFunction()
{
// don't call invalid method
if(!g_func) return;
// call the function, and pass it the userData pointer
// This code does NOT know about C++ code, or the class
// type that you registered.
g_func(g_userData);
}
class MyCallbackObject
{
public:
MyCallbackObject()
{
registerFunc(C_callback, this); //< NOTE: !!this!!
}
~MyCallbackObject()
{
unregisterFunc();
}
// everything else prior exists PURELY to be able to call this C++
// class method, from C code, that has absolutely NO idea about how
// your class is defined.
// NOTE: I'm making this method virtual so that instead of duplicating
// the boiler plate code everywhere, you can just inherit from this
// class, and override the doThing method.
virtual void doThing()
{
/// do you handling here
}
private:
static void C_callback(void* userData)
{
// cast user data to correct class type
MyCallbackObject* obj = (MyCallbackObject*)userData;
// now call the method
obj->doThing();
}
};
老实说,我不能让上面的例子更简单。这个 userData 模式的存在只是为了让您可以从 C 库中调用 C++ 对象的成员函数。希望上面的内容有意义,否则你可能需要阅读静态方法和 C 的局限性。
我在irq header里有这个函数
/* irq.h */
bool irq_InstallISR(int irq, int (*isr)(int, void*), void* isr_data);
和一个class调度器
/* Scheduler.cpp */
using namespace x86Duino;
void Scheduler::init(){
...
irq_InstallISR(RTCIRQ, &Scheduler::timerrtc_isr_handler, isrname_rtc);
...
}
int Scheduler::timerrtc_isr_handler(int irq, void* data){
...
}
我遇到了这个错误
error: cannot convert 'int (x86Duino::Scheduler::*)(int, void*)' to 'int (*)(int, void*)' for argument '2' to 'bool irq_InstallISR(int, int (*)(int, void*), void*)'
我已经在初始化函数中尝试过了
using namespace std::placeholders;
irq_InstallISR(RTCIRQ, std::bind(&Scheduler::timerrtc_isr_handler, this, _1, _2), isrname_rtc);
但是我也遇到了类似的错误
error: cannot convert 'std::_Bind_helper<false, int (x86Duino::Scheduler::*)(int, void*), x86Duino::Scheduler*, const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type {aka std::_Bind<int (x86Duino::Scheduler::*(x86Duino::Scheduler*, std::_Placeholder<1>, std::_Placeholder<2>))(int, void*)>}' to 'int (*)(int, void*)' for argument '2' to 'bool irq_InstallISR(int, int (*)(int, void*), void*)'
请告诉我我做错了什么?
您没有包含 Scheduler::timerrtc_isr_handler 的声明,所以我的第一个猜测是您忘记将该方法声明为静态的?
即在 class 定义中,它应该看起来像:
class Scheduler
{
static int timerrtc_isr_handler(int irq, void* data);
};
irq_InstallISR采用全局函数。错误信息说它不能转换这个原型:
int (Scheduler::*)(int, void*)
里面是一个成员函数,要
int (*)(int, void*)
这是一个普通的 C 函数(或非成员函数,例如静态方法)。
/edit 我猜你想要类似这种模式的东西:
class Scheduler
{
public:
Scheduler()
{
irq_InstallISR(RTCIRQ, timerrtc_isr_handler, this);
}
~Scheduler()
{
// probably want to uninstall the callback here!
}
int isr_handler(int irq)
{
/// do you handling here
}
private:
static int timerrtc_isr_handler(int irq, void* data)
{
// cast user data to correct class type
Scheduler* sch = (Scheduler*)data;
assert(sch); // just in case we get null for some reason?
// thunk call to member function
return sch->isr_handler(irq);
}
};
/编辑 2
您不是在将方法声明为静态或 int 之间进行选择,而是在静态函数(即无权访问 'this')或成员函数(需要 'this').考虑以下因素:
struct Foo
{
void func1() { std::cout << "func1\n"; }
static void func2() { std::cout << "func2\n"; }
};
void bar()
{
// call the static method - does not require an object!
Foo::func2();
// to call func1, we ALWAYS need an object...
Foo obj;
obj.func1();
}
所以让我们更进一步。假设我编写了一个 C-API 库。 C 不支持 C++ classes,因此通常为了与基于 C++ class 的代码进行互操作,您通常会求助于相当常见的用户数据模式。所以我将尝试将其简化为最简单的示例....
/// MyLib.h
// I want to call this method, and it will inturn call any
// callback functions registered with the system.
void callMyRegisteredFunction();
// the type of function I want to call in the previous method
// The C++ way of doing this is to say :
//
// someObject->func();
//
// However in C, without classes, the way you'd call it would be:
//
// func(someObject);
//
// so the second pointer here is the object to call it on.
typedef void (CallbackFunc*)(void*);
// register a callback function, and an associated user-defined object
void registerFunc(CallbackFunc funcPtr, void* userData);
// reset the internal callback
void unregisterFunc();
/// MyLib.cpp
#include "MyLib.h"
// the currently registered callback function
CallbackFunc g_func = NULL;
// the 'object' it is registered against. From 'C' we don't know that
// what type of object this is, we just know it's address.
void* g_userData = NULL;
void registerFunc(CallbackFunc funcPtr, void* userData)
{
g_func = funcPtr;
g_userData = userData;
}
void unregisterFunc()
{
g_func = NULL;
g_userData = NULL;
}
void callMyRegisteredFunction()
{
// don't call invalid method
if(!g_func) return;
// call the function, and pass it the userData pointer
// This code does NOT know about C++ code, or the class
// type that you registered.
g_func(g_userData);
}
class MyCallbackObject
{
public:
MyCallbackObject()
{
registerFunc(C_callback, this); //< NOTE: !!this!!
}
~MyCallbackObject()
{
unregisterFunc();
}
// everything else prior exists PURELY to be able to call this C++
// class method, from C code, that has absolutely NO idea about how
// your class is defined.
// NOTE: I'm making this method virtual so that instead of duplicating
// the boiler plate code everywhere, you can just inherit from this
// class, and override the doThing method.
virtual void doThing()
{
/// do you handling here
}
private:
static void C_callback(void* userData)
{
// cast user data to correct class type
MyCallbackObject* obj = (MyCallbackObject*)userData;
// now call the method
obj->doThing();
}
};
老实说,我不能让上面的例子更简单。这个 userData 模式的存在只是为了让您可以从 C 库中调用 C++ 对象的成员函数。希望上面的内容有意义,否则你可能需要阅读静态方法和 C 的局限性。