【问题标题】:Assign C++ instance method to a global-function-pointer?将 C++ 实例方法分配给全局函数指针?
【发布时间】:2011-02-11 08:24:57
【问题描述】:

您好,

我的项目结构如下:

\- base  (C static library)
     callbacks.h
     callbacks.c
     paint_node.c
     . 
     .
     * libBase.a

\-app (C++ application)
     main.cpp

在 C 库 'base' 中,我已将 global-function-pointer 声明为:

在单头文件中

回调.h

#ifndef CALLBACKS_H_
#define CALLBACKS_H_

extern void (*putPixelCallBack)();
extern void (*putImageCallBack)();

#endif /* CALLBACKS_H_ */

在单个 C 文件中,它们被初始化为

回调.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)’ 到 ‘void ()()'

有什么建议吗?

【问题讨论】:

    标签: c++ c pointers global-variables function-pointers


    【解决方案1】:

    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
    }
    

    您必须以某种方式正确设置全局变量。

    【讨论】:

      【解决方案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;
      }
      

      【讨论】:

        【解决方案3】:

        您也可以使用static 成员函数。可以获取静态成员函数的地址并将其分配给常规函数指针,因为没有 this 指针被隐式传递给它——在幕后,这些函数就像常规非成员函数一样运行。但它们比非成员函数有优势:

        • 静态方法仍然可以访问其类类型的任何对象的privateprotected 成员。
        • 静态方法可以是privateprotected,因此可以控制对其的访问。
        • 使用静态方法可以让您在其所属的类中对功能进行分组。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-02-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-03
          • 1970-01-01
          • 2016-10-23
          相关资源
          最近更新 更多