访问回调c ++的变量外部范围

时间:2012-07-17 19:46:23

标签: c++ callback scope static

我一直在围绕这个静态与非静态,回调函数,函数指针等问题争论不休......我的目标是访问我的回调接口范围之外的结构数据。我正在尝试在我的类TextDetect中执行此操作。当我问这个问题时,我以为自己正在走上正轨:Avoiding a static member function in c++ when using a callback interface from C 但是,我仍然无法访问数据而不会丢失我最感兴趣的数据的范围。在运行时,我得到“访问冲突读取位置...”我会在它失败的地方指出它。 我将上一个问题的答案实现为以下类,完全显示(注意:vtrInitialize是第三方api代码的一部分 int vtrInitialize(const char * inifile,vtrCallback cb,void * calldata); ):

 class TextDetect {
     const char * inifile;
     vtrImage *vtrimage;
     int framecount;
 public:
     TextDetect();
     ~TextDetect();
     void vtrCB(vtrTextTrack *track);
     static void vtrCB_thunk(vtrTextTrack *track, void *calldata);
     int vtrTest(cv::Mat);
     bool DrawBox(cv::Mat&);
     vtrTextTrack *texttrack;
 };

 TextDetect::TextDetect() : inifile("vtr.ini")
 {
      if (vtrInitialize(inifile, vtrCB_thunk, static_cast<void *>(this) ) == -1) 
         std::cout << "Error: Failure to initialize" << std::endl;
         vtrimage = new vtrImage;
  }


  int TextDetect::vtrTest(cv::Mat imagetest)
  {
    /*store image data in an image structure*/
  }

   void TextDetect::vtrCB(vtrTextTrack *track)
   {
     /*send data to command line from callback */                   

我已经尝试过复制我需要的各种方式的数据而且没有任何作用(这段代码是上面的延续):

     //texttrack = track;
     //texttrack = new vtrTextTrack (*track);
     memcpy(texttrack,track,sizeof(*track));
     //vtrTextTrackFree(track); 

    }
  void TextDetect::vtrCB_thunk(vtrTextTrack *track, void *calldata)
  {
       static_cast<TextDetect *>(calldata)->vtrCB(track);
  }

这是我希望使用数据的成员函数。 Texttrack是公共成员,所以我可能也需要在我的课程之外(这段代码是上面的延续):

  bool TextDetect::DrawBox(cv::Mat& tobeboxed)
  {

我在这行代码处获得了运行时的访问冲突错误(此代码是上面的延续):

  if (texttrack->best->ocrconf > 90)
     {
        /*do some more stuff*/
   }
  }

1 个答案:

答案 0 :(得分:1)

希望我能正确理解这一点。

在我看来,问题是试图不正确地复制那些vtrTextTrack结构。 这样:

//texttrack = track;

只需复制指针即可。如果struct的所有者(可能是回调函数的调用者)破坏/删除了vtrTextTrack,那么你将继续使用无效的指针。

这一个:

memcpy(texttrack,track,sizeof(*track));

将复制vtrTextTrack的所有成员,但不会复制其成员指针所指向的内容(例如texttrack->best)。同样,如果所有者破坏/删除了该轨道,那么您将继续使用无效指针。

从那以后

//texttrack = new vtrTextTrack (*track);

不起作用,我猜测vtrTextTrack不提供拷贝构造函数。

至于解决方法,首先检查您的第三方库是否提供了复制这些结构的功能。如果不是这样的话(这可能是设计的吗?),那么你可能必须自己实现一个。这可能很难,因为可能存在各种你不了解的内部结构。如果你不需要整个vtrTextTrack,我会说定义另一个struct并只存储你需要的信息。

的内容
SomeType* bestCopier(SomeType* src)
{
     SomeType* temp;
     /* copy over struct */
     return temp;
}

Foo* fooCopier(Foo* src)
{
    /*...*/
}

struct myTextTrack 
{
public:
    myTextTrack(vtrTextTrack* src)
    {
        //copy over stuff
        m_best = bestCopier(src->best);
        m_foo = fooCopier(src->foo);
    }

private:
    /* the members you care about*/
    SomeType* m_best;
    Foo * m_foo;
}