我使用Cmake& amp;生成了OpenCV二进制文件(.dll)。 visual studio,它生成.pdb文件,帮助我在代码中找到问题(部分!)
此崩溃是如何造成的。
我正在使用一种软件,我们可以为任何特定程序设置互联网下载速度限制(传输速率)。
现在,如果我将IP摄像头连接到下面的代码,我注意到我的应用程序需要大约100Kb / s的互联网使用率(传输速率) - 只有这样我才能无缝地观看直播。 让我说我减少(设置)我的应用程序互联网使用量为10Kb / s [这是崩溃背后的原因] 在这种情况下,我应该能够在4秒多的时间内看到一个新的帧。
我遇到访问冲突错误可能是因为(cap>>img;
)上限正试图到达ram&得到框架,但没有框架YET,因为它仍然被下载由于低互联网速度
显然,指针到达ram中的某个位置以抓取尚未出现的帧。
一些有趣的行为。 。
Void OpenCamera()
{
VideoCapture cap("http://192.168.1.3:8080/video?x.xmjpeg");
Mat img;
while(true)
{
try
{
if(cap.isOpened()) //also tried grab + retrieve, crashes at grab
cap>>img; //code crashes here
}
catch(...)
{
cout<<"Camera Disconnected"<<endl;
}
}
}
如果我在同一个类中使用整个代码(在同一个头文件中),则根本没有问题(新帧在4秒以上显示而不会导致程序崩溃)但如果我将代码放入一个单独的类中(不同的头文件),然后调用该函数从类对象打开相机,然后它崩溃如果 网速减少。
奇怪的行为 - 如果我一步一步调试,它永远不会崩溃!
当我使用ffmpeg构建opencv库时,我只获取opencv(opencv_world310.pdb)的.pdb文件 - 所以没有问题调试使用调用堆栈 但是我没有获得ffmpeg的pdb(因为Opencv_ffmpeg.dll是预编译的,而且它崩溃的地方)
因此难以调试,building ffmpeg不会产生pdb文件因为它使用MSYS构建,所以是否可以使用我们的内容进行调试?
我包括来自visual studio调试的快照, 一些有助于理解的变量:
typedef int (*CvGrabFrame_Plugin)( void* capture_handle ); [cap_ffmpeg_api.cpp]
protected: void* ffmpegCapture; [cap_ffmpeg.cpp]
static CvGrabFrame_Plugin icvGrabFrame_FFMPEG_p = 0; [cap_ffmpeg.cpp]
Sample.exe中的0x0A0AF6F0(opencv_ffmpeg310.dll)抛出异常: 0xC0000005:访问冲突读取位置0x00000020。如果有 这个例外的处理程序,程序可以安全地继续。
在源代码中我包含在line&amp;编译&amp;在项目中使用它 - 没有工作,再次崩溃!
if(ffmpegCapture)
- 空指针检查
我们可以在[cap_ffmpeg.cpp]的第214行进行一些更改以避免崩溃吗? 其他头文件只是一个文件夹。
更新:我注意到当我限制互联网消费速度时程序立即崩溃。我正在使用C ++ / Cli(winforms,目标网络框架= 4.6),我有CameraClass(在单独的头文件中)&amp;主要功能(单独的头文件)
主要功能有以下代码
CameraClass ^CC = gcnew CameraClass();
CC->OpenCamera();
我无法在托管类中创建非管理对象类型,因此我将本机类型(Opencv变量)放入单独的命名空间中,如下所示,以便我可以在此类中使用。可能我必须使用内部指针?
#pragma once
#include"opencv2\opencv.hpp"
#include <msclr\marshal_cppstd.h>
namespace SampleApp{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Threading;
using namespace System::IO;
using namespace std;
namespace
{
cv::VideoCapture cap[5]; //max 5 instance for this class
cv::Mat image[5];
cv::IplImage pic1[5];
cv::IplImage *pic2[5];
}
public ref class CamWindow : public WeifenLuo::WinFormsUI::Docking::DockContent
{
public: CamWindow(void)
{
InitializeComponent();
}
Void OpenCamera()
{
}
.
.
.
.
};
}
.net内存处理和&amp ;; C ++内存处理?
答案 0 :(得分:2)
您可以声明一个非托管类。从托管类中指向它。
public class OpenCVClass
{
public:
Void OpenCamera()
{
VideoCapture cap("http://192.168.1.3:8080/video?x.xmjpeg");
Mat img;
while(true)
{
try
{
if(cap.isOpened())
cap>>img;
}
catch(...)
{
cout<<"Camera Disconnected"<<endl;
}
}
}
public ref class managed
{
public:
managed(){}
~managed(){}
static OpenCVClass* unmanaged = new OpenCVClass();
unmanaged->OpenCVClass();
};
}
如果dll是在MSYS上构建的,则可以使用addr2line command将DLL中的地址转换为源代码行,或者在托管类的函数中使用非托管变量。