本人尝试封装paddleocr,给C#直接调用,但是每次到调封装的C++方法时就会报错:“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。” ,始终难以解决,下面时我的C#代码:
[DllImport("ocr_system.dll", EntryPoint = "LoadModel", SetLastError = true, CharSet = CharSet.Ansi)]
static extern IntPtr LoadModel(ref byte[] input, int height, int width); //out IntPtr seg_res
private void button1_Click(object sender, EventArgs e)
{
string image_path = "C:/Users/soft016/Desktop/Test/t1.jpg";
Bitmap bmp = new Bitmap(image_path);
int stride;
byte[] source = GetBGRValues(bmp, out stride);
IntPtr seg_img = LoadModel(ref source, bmp.Width, bmp.Height);
Mat img = new Mat(seg_img);
Bitmap seg_show = new Bitmap(img.Cols, img.Rows, (int)img.Step(), System.Drawing.Imaging.PixelFormat.Format24bppRgb, img.Data);
pictureBox1.Image = seg_show;
}
下面时C++里面的方法:
extern "C" __declspec(dllexport) cv::Mat * LoadModel(char* input, int width, int height);
__declspec(dllexport) cv::Mat* LoadModel(char* input, int width, int height)
{
C++代码
}
执行到C#代码的 IntPtr seg_img = LoadModel(ref source, bmp.Width, bmp.Height); 就会报错提示 ,求解答
只是这些,是看不出来的。C++报内存错误,有很多原因导致的。
这通常表示你的指针飞了,要访问的不是你的程序申请的内存
你起码在c++下先测试过,再拿去给别的程序调用
(ref byte[] input, int height, int width); //out IntPtr seg_res
第一个参数无需ref,正常调用就是 input[0]的指针
byte[] input = new byte[] { 0x01, 0x02 };
var input_ptr = Marshal.UnsafeAddrOfPinnedArrayElement(input, 0);
注意前提保证,从代码上我看得出是图像操作,名字上BGR也看得出是3分量,所以防御性代码是需要检测一下这个byte[]的数量是否合规,以避免数据量不对,访问内存越界
if(input.length==宽*高*3)