1

私は、静的対非静的、コールバック関数、関数ポインターなどのこの問題について頭を悩ませてきました。私の目標は、コールバックインターフェイスの範囲外の構造体のデータにアクセスすることです。TextDetectというクラス内でこれを実行しようとしています。この質問をしたとき、私は順調に進んでいると思いました。Cからのコールバックインターフェイスを使用するときに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*/
   }
  }
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 に答える