问候,
我的项目结构如下:
\- base (C static library)
callbacks.h
callbacks.c
paint_node.c
.
.
* libBase.a
\-app (C++ application)
main.cpp
在C库'base'中,我将global-function-pointer声明为:
单头文件中的
callbacks.h
#ifndef CALLBACKS_H_
#define CALLBACKS_H_
extern void (*putPixelCallBack)();
extern void (*putImageCallBack)();
#endif /* CALLBACKS_H_ */
在单个C文件中,它们被初始化为
的callbacks.c
#include "callbacks.h"
void (*putPixelCallBack)();
void (*putImageCallBack)();
其他C文件访问此回调函数:
paint_node.c
#include "callbacks.h"
void paint_node(node *node,int index){
//Call callbackfunction
.
.
putPixelCallBack(node->x,node->y,index);
}
我编译这些C文件并生成一个静态库'libBase.a'
然后在C ++应用程序中,
我想将C ++实例方法分配给这个全局函数指针:
我做了类似的事情:
在Sacm.cpp文件中
#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();
}
但是在编译它时会出现错误:
sacmtest.cpp:在成员函数'void中 SACM :: doDetection()”: sacmtest.cpp:113:错误:ISO C ++ 禁止取得地址 不合格或括号内的 非静态成员函数形成一个 指向成员函数的指针。说 '& Sacm :: paintPixel'sacmtest.cpp:113: 错误:从'void转换 (Sacm :: )(int,int,int)'to'void ()()”
任何提示?
答案 0 :(得分:7)
这在C ++常见问题解答[1]中得到了解答。这不起作用,因为指针不与特定对象实例相关联。解决方案也在那里,创建一个使用特定对象的全局函数:
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
}
你必须以某种方式正确设置全局变量。
答案 1 :(得分:2)
您无法将实例方法指针转换为普通函数指针。解决方法是使用另一个全局变量来保存实例和一个用作回调的全局包装函数,然后调用实例方法:
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;
}
答案 2 :(得分:2)
您也可以使用static
成员函数。可以获取静态成员函数的地址并将其分配给常规函数指针,因为没有this
指针隐式传递给它 - 在引擎盖下,这些函数就像常规的非成员函数一样运行。但它们优于非成员函数:
private
和protected
成员。private
或protected
,因此可以控制对它的访问。