我将使用 C ++ 创建的dll
创建一个C#应用程序来捕获网络摄像头。这个dll
允许我访问OpenCV
库。目前,我使用 Visual Studio 2013 表达式和OpenCV 2.49
版本。我已经成功地在 C ++ 程序中捕获了Webcam。当我将其构建到dll
并从C#代码中读取此dll
时,发生了错误。错误内容是:
An unhandled exception of type 'System.AccessViolationException' occurred in Webcam.exe
Additional Information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
我用C ++构建的dll
代码喜欢这个。
#include <iostream>
#include <Windows.h>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\core\core.hpp>
typedef struct _IplImageCs
{
int width;
int height;
int imageSize;
}
IplImageCs;
typedef IplImageCs* pIplImageCs;
extern "C"
{
_declspec(dllexport) int CaptureFromCamera(int num, pIplImageCs imgCs);
_declspec(dllexport) void QueryFrame(LPBYTE imageData);
_declspec(dllexport) void ReleaseCaptureCamera(void);
}
IplImage* img;
CvCapture* capture;
pIplImageCs imgCs;
_declspec(dllexport) int CaptureFromCamera(int num, pIplImageCs imgCs)
{
//capture = cvCaptureFromCAM(num);
capture = cvCreateCameraCapture(num);
if (capture == NULL)
return -1;
img = cvQueryFrame(capture);
imgCs->width = img->width;
imgCs->height = img->height;
imgCs->imageSize = img->imageSize;
return 0;
}
_declspec(dllexport) void QueryFrame(LPBYTE imageData)
{
if (capture == NULL)
return;
img = cvQueryFrame(capture);
memcpy(imageData, img->imageData, img->imageSize);
}
_declspec(dllexport) void ReleaseCaptureCamera(void)
{
cvReleaseCapture(&capture);
}
在C#中,我写了这个。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Webcam
{
public partial class Form1 : Form
{
private bool bContinue;
private bool bCompleted;
private BackgroundWorker bw;
private Bitmap bmp;
[StructLayout(LayoutKind.Sequential)]
private struct IplImage
{
public int width;
public int height;
public int imageSize;
public IplImage(int init)
{
width = init;
height = init;
imageSize = init;
}
}
IplImage img;
[DllImport("Show Camera.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int CaptureFromCamera(int num, ref IplImage img);
[DllImport("Show Camera.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void QueryFrame(Byte[] imageData);
[DllImport("Show Camera.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void ReleaseCaptureCamera();
public Form1()
{
InitializeComponent();
panel2.AutoScroll = true;
bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(Processing);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedProcessing);
bCompleted = true;
img = new IplImage(0);
}
private void ShowBt_Click(object sender, EventArgs e)
{
try
{
CaptureFromCamera(0, ref img);
//if (CaptureFromCamera(0, ref img) < 0)
// return;
int width = img.width;
int height = img.height;
pb.Size = new Size(width, height);
this.ClientSize = new Size(panel1.Width + panel2.Width, panel2.Height);
bContinue = true;
bCompleted = false;
bw.RunWorkerAsync();
ShowBt.Enabled = false;
}
catch(Exception error)
{
MessageBox.Show(error.Message);
}
}
private void Processing(object sender,DoWorkEventArgs e)
{
try
{
if (CaptureFromCamera(0, ref img) < 0)
return;
this.Cursor = Cursors.WaitCursor;
Byte[] imageData = new Byte[img.imageSize];
while (bContinue)
{
QueryFrame(imageData);
bmp = new Bitmap(img.width, img.height, PixelFormat.Format24bppRgb);
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
IntPtr ptr = bmpData.Scan0;
Marshal.Copy(imageData, 0, ptr, img.imageSize);
bmp.UnlockBits(bmpData);
pb.Image = bmp;
bmp.Dispose();
}
}
catch(Exception error)
{
MessageBox.Show(error.Message);
}
}
private void CompletedProcessing(object sender, RunWorkerCompletedEventArgs e)
{
bCompleted = true;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
bContinue = false;
while (bCompleted != true)
Application.DoEvents();
}
private void QuitBt_Click(object sender, EventArgs e)
{
Close();
}
}
}
我不知道如何更正代码以使其正常工作。有人能帮我解决吗?非常感谢您阅读我的问题并帮助我。祝你周末愉快!