我一直在围绕这个静态与非静态,回调函数,函数指针等问题争论不休......我的目标是访问我的回调接口范围之外的结构数据。我正在尝试在我的类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*/
}
}
答案 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;
}