[OpenCV] C# 에서 C++ DLL 사용하기
OpenCV 2026. 2. 18. 15:36 |C#에서 로드한 OpenCV 데이터를 C++ DLL 함수로 처리해 보자.
가장 효율적인 방법은 맨 아래 '가장 효율적인 방법'을 참고한다.
C++ DLL 프로젝트를 만들고 OpenCV 라이브러리를 설정한 후 아래 코드를 빌드하고 DLL 파일을 만든다.
<Dll.h>
#pragma once
#include "opencv2/opencv.hpp"
extern "C" __declspec(dllexport) void cvt(uchar* srcData, int width, int height, int channels, int type);
<Dll.cpp>
#include "DllHeader.h"
extern "C" __declspec(dllexport) void cvt(uchar* srcData, int width, int height, int channels, int type)
{
cv::Mat temp(height, width, type); // height, width, type 순이다.
// Mat의 형식이 항상 일정하다면 temp를 전역 변수로 선언해 두고 사용하는게 효율적.
memcpy(temp.data, srcData, width * height * channels); // 소스 데이터 복사.
//cv::cvtColor(temp, temp, cv::COLOR_BGR2GRAY); 이건 컬러 채널이 (3채널에서 1채널로) 바뀌기 때문에 에러가 발생한다.
cv::cvtColor(temp, temp, cv::COLOR_BGR2RGB); // 컬러 순서 변경.
//cv::imshow("temp", temp);
//cv::waitKey(0);
memcpy(srcData, temp.data, width * height * channels); // 변경된 데이터를 소스에 복사.
}
좀 더 효율적인 <Dll.cpp>를 만들기 위해 memcpy()를 사용하지 않고 데이터 위치 포인터(srcData)를 그대로 대입한다.
#include "DllHeader.h"
extern "C" __declspec(dllexport) void cvt(uchar* srcData, int width, int height, int channels, int type)
{
cv::Mat temp(height, width, type); // height, width, type 순이다.
// Mat의 형식이 항상 일정하다면 temp를 전역 변수로 선언해 두고 사용하는게 효율적.
temp.data = srcData; // 이미지 정보 포인터 변경.
// 만약 temp를 전역변수로 둔다면 width, height, channels, type 정보도 필요 없다.
cv::cvtColor(temp, temp, cv::COLOR_BGR2RGB); // 컬러 순서 변경.
}
아래 링크를 참고해 OpenCVSharp 프로젝트를 준비한다.
2021.11.20 - [OpenCV] - OpenCV with C#

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using OpenCvSharp;
namespace OpenCVSharp
{
public partial class Form1 : Form
{
// 위에서 만든 C++ DLL 파일을 프로젝트 디렉토리에 복사한다.
// DLL 파일에서 C++용 OpenCV 라이브러리를 사용하므로 프로젝트 디렉토리에도
// opencv_worldXXX.dll 파일이 있어야 한다.
// 프로젝트 빌드시 AnyCPU가 아닌, DLL과 같은 아키텍쳐(x64)로 바꿔야 한다.
[DllImport("Dll.dll")] // DLL 임포트.
public extern static void cvt(IntPtr srcData, int width, int height, int channels, int type);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
Mat mat = Cv2.ImRead(dlg.FileName);
// DLL 함수 사용.
cvt(mat.Data, mat.Width, mat.Height, mat.Channels(), mat.Type().Value);
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
// Mat to Bitmap
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(mat.ToBytes());
pictureBox1.Image = new Bitmap(memoryStream);
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
}
}

※ 참고
가장 효율적인 방법 (아래 더보기 클릭)
OpenCVSharp에서 사용하는 Mat과 C++ OpenCV에서 사용하는 Mat은 서로 다르지만 OpenCVSharp Mat.CvPtr 포인터에 C++ OpenCV Mat 구조체의 위치가 저장되어 있다. 이 구조체를 C++ 에서 그대로 사용할 수 있다.
<Dll.h>
#pragma once
#include "opencv2/opencv.hpp"
extern "C" __declspec(dllexport) void cvt(cv::Mat* mat);
<Dll.cpp>
#include "DllHeader.h"
extern "C" __declspec(dllexport) void cvt(cv::Mat* mat)
{
cv::cvtColor(*mat, *mat, cv::COLOR_BGR2RGB);
}
<Form.cs>
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using OpenCvSharp;
namespace OpenCVSharp
{
public partial class Form1 : Form
{
// 위에서 만든 C++ DLL 파일을 프로젝트 디렉토리에 복사한다.
// DLL 파일에서 C++용 OpenCV 라이브러리를 사용하므로 프로젝트 디렉토리에도
// opencv_worldXXX.dll 파일이 있어야 한다.
// 프로젝트 빌드시 AnyCPU가 아닌, DLL과 같은 아키텍쳐(x64)로 바꿔야 한다.
[DllImport("Dll.dll")] // DLL 임포트.
public extern static void cvt(IntPtr mat);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
Mat mat = Cv2.ImRead(dlg.FileName);
// DLL 함수 사용. Mat.CvPtr: Native pointer of OpenCV structure.
cvt(mat.CvPtr);
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
}
// Mat to Bitmap
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(mat.ToBytes());
pictureBox1.Image = new Bitmap(memoryStream);
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
}
}
※ 참고
2026.02.19 - [OpenCV] - [OpenCV] Python 에서 C++ DLL 사용하기
2025.02.16 - [OpenCV] - C# and Python OpenCV Image Data Share (Memory Mapped File)
2025.02.23 - [OpenCV] - C and Python OpenCV Image Data Share (Memory Mapped File)
'OpenCV' 카테고리의 다른 글
| [OpenCV] Python 에서 C++ DLL 사용하기 (0) | 2026.02.19 |
|---|---|
| [OpenCV] Device(Camera) Enumerator 카메라 구분하기 (0) | 2026.02.16 |
| [OpenCV] Desktop Capture 화면 캡쳐 (0) | 2026.02.11 |
| OpenCV Contour Nozzle Dripping Detection (0) | 2025.04.29 |
| IP Camera ONVIF Protocol (0) | 2025.03.01 |
