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

    }
}

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