C# 調用C++編寫DLL
做大神的搬運工 如有侵權請聯繫我刪除
點擊這裏
使用過程中出現了報錯情況:
System.BadImageFormatException
點擊這裏
補充使用:
問題點:結構體方式傳遞數據,非常方便。但是會出現報錯的情況.
“無法封送處理“parameter #1”: 內部限制: 結構太複雜或太大。”
使用指針傳遞數據大數據;(圖片等數據)
C++ DLL部分
創建的頭文件 MagicStickDll.h
#pragma once
//圖片信息
struct ImageInfo
{
public:
int width;
int height;
int nBandNum;
};
//設置圖片 參數使用了 結構體與 指針;
extern "C" _declspec(dllexport) void __stdcall SetImageData(ImageInfo& imageInfo, BYTE* pImage);
MagicStickDll.cpp
// MagicStickDll.cpp : 定義 DLL 應用程序的導出函數。
//
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
#include "stdafx.h"
#include "MagicStickDll.h"
//************************************
// Method: TransBufferToMat
// FullName: 圖片buffer數據轉換成 Mat數據格式;
// Access: public
// Returns: cv::Mat
// Qualifier:
// Parameter: unsigned char * pBuffer 圖片數據內容
// Parameter: int nWidth 圖片的寬度
// Parameter: int nHeight 圖片的高度
// Parameter: int nBandNum 每個像素包含數據個數 (1, 3, 4 ) 1:Gray 3:RGB 4:RGBA
// Parameter: int nBPB 每個像素數據 所佔位數(1, 2) 1:8位 2:16位;
//************************************
cv::Mat TransBufferToMat(BYTE* pBuffer, int nWidth, int nHeight, int nBandNum, int nBPB = 1)
{
cv::Mat mDst;
if (nBandNum == 4)
{
if (nBPB == 1)
{
mDst = cv::Mat::zeros(cv::Size(nWidth, nHeight), CV_8UC4);
}
else if (nBPB == 2)
{
mDst = cv::Mat::zeros(cv::Size(nWidth, nHeight), CV_16UC4);
}
}
else if (nBandNum == 3)
{
if (nBPB == 1)
{
mDst = cv::Mat::zeros(cv::Size(nWidth, nHeight), CV_8UC3);
}
else if (nBPB == 2)
{
mDst = cv::Mat::zeros(cv::Size(nWidth, nHeight), CV_16UC3);
}
}
else if (nBandNum == 1)
{
if (nBPB == 1)
{
mDst = cv::Mat::zeros(cv::Size(nWidth, nHeight), CV_8UC1);
}
else if (nBPB == 2)
{
mDst = cv::Mat::zeros(cv::Size(nWidth, nHeight), CV_16UC1);
}
}
for (int j = 0; j < nHeight; ++j)
{
BYTE* data = mDst.ptr<BYTE>(j);
BYTE* pSubBuffer = pBuffer + (nHeight - 1 - j) * nWidth* nBandNum*nBPB;
memcpy(data, pSubBuffer, nWidth*nBandNum*nBPB);
}
if (nBandNum == 1)
{
cv::cvtColor(mDst, mDst, cv::COLOR_GRAY2BGR);
}
else if (nBandNum == 3)
{
cv::cvtColor(mDst, mDst, cv::COLOR_RGB2BGR);
}
else if (nBandNum == 4)
{
cv::cvtColor(mDst, mDst, cv::COLOR_RGBA2BGR);
}
return mDst;
}
//設置圖片;
void __stdcall SetImageData(ImageInfo& imageInfo, BYTE* pImage)
{
cv::Mat colorImage = TransBufferToMat(pImage, imageInfo.width, imageInfo.height, imageInfo.nBandNum);
//顯示圖片數據;
cout << "寬度" << imageInfo.width << endl;
cout << "高度" << imageInfo.height << endl;
cv::imshow("彩色圖片", colorImage);
cv::waitKey(0);
}
stdafx.h
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // 從 Windows 頭中排除極少使用的資料
// Windows 頭文件:
#include <windows.h>
#include "MagicStickDll.h"
MyDll.def
LIBRARY "MagicStickDll"
EXPORTS
SetImageData @ 1
C# 調用側
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace MagicStickTester
{
class Program
{
//Dll函數導出;
//設置圖片數據; dll位置根據實際清空設置;
[DllImport(@"../../../x64/Debug/MagicStickDll.dll", EntryPoint = "SetImageData", SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
public extern static void SetImageData(ref ImageInfo imageData, [MarshalAs(UnmanagedType.LPArray)]byte[] groupVal);
public static void SetImage(ref byte[] imageData)
{
int size = imageData.Length;
int width = 300;
int height = 200;
int nBandNum = 4;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (j < 100)
{
imageData[i * width * nBandNum + j * nBandNum] = 255;
imageData[i * width * nBandNum + j * nBandNum + 1] = 0;
imageData[i * width * nBandNum + j * nBandNum + 2] = 0;
imageData[i * width * nBandNum + j * nBandNum + 3] = 0;
}
else if (100 <= j && j < 200)
{
imageData[i * width * nBandNum + j * nBandNum] = 0;
imageData[i * width * nBandNum + j * nBandNum + 1] = 255;
imageData[i * width * nBandNum + j * nBandNum + 2] = 0;
imageData[i * width * nBandNum + j * nBandNum + 3] = 0;
}
else if (j >= 200)
{
imageData[i * width * nBandNum + j * nBandNum] = 0;
imageData[i * width * nBandNum + j * nBandNum + 1] = 0;
imageData[i * width * nBandNum + j * nBandNum + 2] = 255;
imageData[i * width * nBandNum + j * nBandNum + 3] = 0;
}
}
}
}
static void Main(string[] args)
{
//設置圖片基本信息 寬、高、像素位數
ImageInfo imageInfo = new ImageInfo();
imageInfo.width = 300;
imageInfo.height = 200;
imageInfo.nBandNum = 4;
//設置圖片數據內容;
int imageSize = imageInfo.width * imageInfo.height * imageInfo.nBandNum;
byte[] imageBytes = new byte[imageSize];
SetImage(ref imageBytes);
//調用DLL中函數,
SetImageData(ref imageInfo, imageBytes);
}
//導出 Dll內結構體;
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct ImageInfo
{
public int width; //圖片寬度;
public int height; //圖片高度;
public int nBandNum; //像素大小;
};
}
}