2011-09-10 130 views
0

我是新的C++, 我得到的访问冲突异常每当我试图构造一个对象 的构造函数如下所示访问冲突OpenCV的C++ DLL

Image::Image(IplImage* pIplImage, bool bDestroy) 
    : m_bOwned(bDestroy) 
{ 
    memcpy(static_cast< IplImage* >(this), pIplImage, sizeof(IplImage)); 

    if (bDestroy) 
     cvReleaseImageHeader(&pIplImage); 

} 

和析构函数是

Image::~Image() 
{ 
    if (m_bOwned) 
     cvFree(reinterpret_cast< void** >(&imageDataOrigin)); 
} 

编辑1:类定义

class VISION_EXPORT Image 
    : public IplImage 
    , private boost::noncopyable 
{ 
public: 

explicit Image(IplImage* pIplImage, bool bDestroy = true); 
~Image(); 
private:  
bool m_bOwned; 
}; 

这是工作之前,但现在当我将它导出为DLL ..它不再工作。 你能帮我吗?

+0

为什么当库提供了一个C++接口时,您需要自己的OpenCV映像结构的C++包装? –

+0

它是中间件的一部分,我应该照原样使用它。 –

+0

你从哪里得到访问违规? IT可能只是因为你写过一个数组的末尾并通过堆写入,这会导致后续分配抛出访问冲突。 – Goz

回答

2

您不能执行memcpy(),它会写入this指针指向的内存。当你这样做时,你会抛弃对象的内部结构。相反,你应该做的是将一个成员变量添加到你的Image类中。例如:

class Image { 
protected: 
    pIplImage* m_pImage; 
    bool m_bOwned; 
// ... whatever else you need here ... 
}; 

那么你的实现可能是这样的:

Image::Image(IplImage* pIplImage, bool bDestroy) 
: m_pImage(pIplImage), m_bOwned(bDestroy) 
{ 
} 

Image::~Image() 
{ 
    if (m_bOwned) 
     cvReleaseImage(m_pImage); 
} 

正如你看到的上面,我不认为你需要复制任何数据。实例化这个类的代码决定它是否想将图像的所有权传递给类,但是Image类只是复制指针。

编辑:看完你的代码后,我想我有一个什么可能是错的想法。传递给构造函数的IplImage指针由主应用程序分配并由DLL删除。我敢打赌,问题是由两个不同的分配器在同一块内存上执行操作引起的。你应该确保内存分配和释放相同的分配功能。您甚至可能会将OpenCV与您的主应用程序以及您的DLL链接在一起,并且这些是同一个库的两个单独实例。

编辑#2:有关该问题的更深入解释,请参阅this article。正如我在评论中所说的,如果你想避免这个问题,你需要重新组织代码以避免跨模块内存分配/释放。

+0

非常感谢..但问题是我不允许在包装中更改,因为它在许多其他类中使用。我试图跟踪错误的来源,它似乎是析构函数。你能帮我解决这个问题吗? –

+0

正如我所说,你所做的并不能保证工作,C++类的布局与大多数情况下的结构不同,所以你不能将数据拷贝到这个指针指向的内存中。张贴更多的代码,特别是你应该展示如何定义Image类。 – Miguel

+0

我编辑了问题,现在它包含类定义 –