2012-07-17 40 views
1

我一直在徘徊在这个问题的静态与非静态,回调函数,函数指针等...我的目标是访问一个结构的数据范围之外我的回调界面。我正在尝试在我的课程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);):访问变量超出回调范围C++

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*/ 
    } 
    } 
+5

老实说,是真的那么多的代码来描述你的问题? – 2012-07-17 19:49:35

+0

你写在表单上的问题很难快速理解;也许简化它会促使更多人回答。 – 2012-07-17 19:51:42

+1

嗯,你的'memcpy'确实是一个错误:它不可能复制'track'的所有内容,因为你显然在'track'中有指针,它将被复制,但不是它们指向的内容。我可以很容易想象,在回调之外,“track”数据不存在。 – fork0 2012-07-17 19:57:51

回答

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; 
} 
+0

谢谢你的回答。让我玩你的想法并报告回来。 – user1530101 2012-07-18 13:22:28

+0

当我玩这个问题来了。 1)最好的API vtrTextTrack是一个指针。这是否意味着上例中的SomeType应该是SomeType * best?这会改变你的例子中的任何东西吗? 2)SomeType实际上是另一个结构(在C而不是C++中)。这是否意味着我必须为上面示例中声明的结构创建自己的拷贝构造函数? SomeType也有指针。 – user1530101 2012-07-18 13:53:51

+0

你说得对,我的代码不太对。我做了一些改变,而这只是一种你可以接近的方法。由于这些都是C结构,并且没有拷贝构造函数,因此您可能只需为每个部分编写一个拷贝函数。这不会很有趣,这是肯定的。你需要保留实际的vtrTextTrack结构,还是只保留其中的某些信息?因为后者会更容易。此外,值得回顾一下,并考虑是否有另一种方式来完成与第三方库模型更好相同的事情。 – Ari 2012-07-18 15:57:15