1

我一直在思考静态与非静态、回调函数、函数指针等问题。我的目标是访问回调接口范围之外的结构数据。我正在尝试在我的名为 TextDetect 的课程中​​执行此操作。当我问这个问题时,我以为我走上了正轨:使用 C 中的回调接口时避免 C++ 中的静态成员函数 但是,我仍然无法访问数据而不会丢失我最感兴趣的数据的范围。在运行时,我得到“访问冲突读取位置......”我会在下面指出它失败的地方。我将上一个问题的答案实现为以下类,完全显示(注意:vtrInitialize 是第 3 方 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*/
   }
  }
4

1 回答 1

1

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

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

//texttrack = track;

只是复制指针。如果结构的所有者(可能是回调函数的调用者)破坏/删除了 vtrTextTrack,那么您将持有一个无效的指针。

这个:

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

将复制 vtrTextTrack 的所有成员,但不会复制其成员指针所指向的内容(例如texttrack->best)。同样,如果所有者销毁/删除轨道,那么您将持有无效指针。

而且因为

//texttrack = new vtrTextTrack (*track);

没用,我猜 vtrTextTrack 不提供复制构造函数。

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

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;
}
于 2012-07-17T20:53:32.093 回答