Greetings,
My project structure is as follows:
\- base (C static library)
callbacks.h
callbacks.c
paint_node.c
.
.
* libBase.a
\-app (C++ application)
main.cpp
In C library 'base' , I have declared global-function-pointer as:
in singleheader file
callbacks.h
#ifndef CALLBACKS_H_
#define CALLBACKS_H_
extern void (*putPixelCallBack)();
extern void (*putImageCallBack)();
#endif /* CALLBACKS_H_ */
in single C file they are initialized as
callbacks.c
#include "callbacks.h"
void (*putPixelCallBack)();
void (*putImageCallBack)();
Other C files access this callback-functions as:
paint_node.c
#include "callbacks.h"
void paint_node(node *开发者_高级运维node,int index){
//Call callbackfunction
.
.
putPixelCallBack(node->x,node->y,index);
}
I compile these C files and generate a static library 'libBase.a'
Then in C++ application,
I want to assign C++ instance method to this global function-pointer:
I did something like follows :
in Sacm.cpp file
#include "Sacm.h"
extern void (*putPixelCallBack)();
extern void (*putImageCallBack)();
void Sacm::doDetection()
{
putPixelCallBack=(void(*)())&paintPixel;
//call somefunctions in 'libBase' C library
}
void Sacm::paintPixel(int x,int y,int index)
{
qpainter.begin(this);
qpainter.drawPoint(x,y);
qpainter.end();
}
But when compiling it gives the error:
sacmtest.cpp: In member function ‘void Sacm::doDetection()’: sacmtest.cpp:113: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&Sacm::paintPixel’ sacmtest.cpp:113: error: converting from ‘void (Sacm::)(int, int, int)’ to ‘void ()()’
Any tips?
This is answered in the C++ FAQ, [1]. This doesn't work, because the pointer isn't associated with a particular object instance. The solution is given there too, create a global function that uses a particular object:
Sacm* sacm_global;
void sacm_global_paintPixel(int x,int y,int index)
{
sacm_global->paintPixel(x, y, index);
}
void Sacm::doDetection()
{
putPixelCallBack = &sacm_global_paintPixel;
//call somefunctions in 'libBase' C library
}
You have to somehow setup the global variable properly.
You cannot convert an instance method pointer to a normal function pointer. A workaround is to use another global variable to hold the instance and a global wrapper function that is used as the callback and then in turn calls the instance method:
Sacm *callbackSacm;
extern "C" // since it sounds like it's called from a C library
void call_paintPixel(int x, int y, int index) {
callbackSacm->paintPixel(x, y, index);
}
void Sacm::doDetection() {
callbackSacm = this;
putPixelCallBack = call_paintPixel;
}
You can alternatively use a static
member function. The address of a static member function can be taken and assigned to a regular function pointer, because no this
pointer is implicitly passed to it -- under the hood, these functions operate just like regular non-member functions. But they have advantages over non-member functions:
- A static method still has access to the
private
andprotected
members of any object of its class type. - A static method can be
private
orprotected
so access to it can be controlled. - Using a static method lets you and group functionality inside the class, where it belongs.
精彩评论