C# 調用C++編寫DLL

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;    //像素大小;
        };

    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章