c#与c++交互的一些东西

最近做一个项目,对方公司只提供了一个c++的DLL,但没封住,c#无法DllImport.所以只能自己写c++来封住了。

对方的Dll只接收yuv420的图片格式,所以在c++里用opencv来转换。本来想C#来写,但总觉得麻烦。

【C#】代码

public void Do(Bitmap bp)

{ 

Bitmap outIMG = new Bitmap(bp.Width,bp.Height);

System.Drawing.Imaging.BitmapData bmpData = bp.LockBits(new System.Drawing.Rectangle(0, 0, bp.Width, bp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite,
bp.PixelFormat);

System.Drawing.Imaging.BitmapData bmpData1 = outIMG .LockBits(new System.Drawing.Rectangle(0, 0, outIMG .Width, outIMG .Height), System.Drawing.Imaging.ImageLockMode.ReadWrite,
outIMG .PixelFormat);
CFunction(bmpData.Scan0, bp.Width, bp.Height, 3, 0,bmpData1.Scan0);
img.UnlockBits(bmpData);

outIMG.UnlockBits(bmpData1 );

}

【C++】代码

extern "C" __declspec(dllexport) void WINAPI CFunction(unsigned char* img,int width,int height,int ch,int format,unsigned char* outImg)
{
  Mat frame(Size(width, height), CV_8UC(ch), img); 

  Mat dest;
  cvtColor(frame, dest, format == 0 ? CV_BGR2YUV_I420 : CV_RGB2YUV_I420);

  第三方Dll(dest);

  Mat rgb;

  cvtColor(dest, rgb, format == 0 ? CV_YUV2BGR_I420 : CV_YUV2RGB_I420);

  memcpy((void*)outImg, (void*)dest.data, rgb.cols * rgb.rows * rgb.channels());
}

这基本实现了c++和c#直接图片的对接。但是这种做法会卡C#的程序,我试过backgroundworker,task,很多种方法,但是c#就是会卡住的。具体原因不太清楚,所以觉得这部分的处理在c++中用线程来做,

做完之后通知c#,因为我需要在第三方DLL来生成四个结果图片。所以定义了结构体。

【C#】

[StructLayout(LayoutKind.Sequential)]
public struct ImageResult
{
public IntPtr First;
public IntPtr Second;
public IntPtr Third;
public IntPtr Forth;
}

【C++】

struct ImgeResult
{
void * FirstIMG;
void* SecondIMG;
void* ThirdIMG;
void* FouthIMG;
};

接着要在c#做定义给C++回调的委托。

【c#】

public delegate void CSCallback(ImageResult ir);

public static CSCallback callback;

callback = CSCallbackFunction;

SetCallback(callback );

public static void CSCallbackFunction(ImageResult tick)
{
  处理c++返回的数据
}

调用c++线程函数

public void Do(Bitmap bp)

{ 

Bitmap outIMG = new Bitmap(bp.Width,bp.Height);

System.Drawing.Imaging.BitmapData bmpData = bp.LockBits(new System.Drawing.Rectangle(0, 0, bp.Width, bp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite,
bp.PixelFormat);

DoImage(bmpData.Scan0, bp.Width, bp.Height, 3, 0,bmpData1.Scan0);
img.UnlockBits(bmpData);

outIMG.UnlockBits(bmpData1 );

}

【c++】

typedef void(__stdcall *CPPCallback)(ImgeResult ir);

CPPCallback myCallback;

extern "C" __declspec(dllexport) void WINAPI SetCallback(CPPCallback callback)
{
myCallback = callback;
}

void  OperateImage(unsigned char* img,int width,int height,int ch,int format)
{
Mat frame(Size(width, height), CV_8UC(ch), img);
Mat dest;
cvtColor(frame, dest, format == 0 ? CV_BGR2YUV_I420 : CV_RGB2YUV_I420);
Mat second;
cvtColor(frame, second, format == 0 ? CV_BGR2YUV_I420 : CV_RGB2YUV_I420);
Mat third;
cvtColor(frame, third, format == 0 ? CV_BGR2YUV_I420 : CV_RGB2YUV_I420);
Mat forth;
cvtColor(frame, forth, format == 0 ? CV_BGR2YUV_I420 : CV_RGB2YUV_I420);
Mat nextFirst;
Mat nextSecond;
Mat nextThird;
Mat nextTForth;
 //第三方库处理图片

cvtColor(dest, nextFirst, format == 0 ? CV_YUV2BGR_I420 : CV_YUV2RGB_I420);
cvtColor(second, nextSecond, format == 0 ? CV_YUV2BGR_I420 : CV_YUV2RGB_I420);
cvtColor(third, nextThird, format == 0 ? CV_YUV2BGR_I420 : CV_YUV2RGB_I420);
cvtColor(forth, nextTForth, format == 0 ? CV_YUV2BGR_I420 : CV_YUV2RGB_I420);
ReleaseBelleFaceEngine();
ir.FirstIMG = (void *)malloc(nextFirst.cols * nextFirst.rows * nextFirst.channels());
ir.SecondIMG = (void *)malloc(nextSecond.cols * nextSecond.rows * nextSecond.channels());
ir.ThirdIMG = (void *)malloc(nextThird.cols * nextThird.rows * nextThird.channels());
ir.FouthIMG = (void *)malloc(nextTForth.cols * nextTForth.rows * nextTForth.channels());
memcpy(ir.FirstIMG, (void*)nextFirst.data, nextFirst.cols * nextFirst.rows * nextFirst.channels());
memcpy(ir.SecondIMG, (void*)nextSecond.data, nextSecond.cols * nextSecond.rows * nextSecond.channels());
memcpy(ir.ThirdIMG, (void*)nextThird.data, nextThird.cols * nextThird.rows * nextThird.channels());
memcpy(ir.FouthIMG, (void*)nextTForth.data, nextTForth.cols * nextTForth.rows * nextTForth.channels());

myCallback(ir);
}

extern "C" __declspec(dllexport) void WINAPI DoImage(unsigned char* img,int width,int height,int ch,int format)
{
std::thread th1(OperateImage, img, width, height,ch,format);
th1.detach();
}

到此不会卡住c#程序。

由于本人第一次用c++,也是一边查,一边写的。

c++写的一些心得.

(1)使用opencv要注意链接库是debug还是release的。

(2)到纯净系统下要安装redist,我的目标机是64位,开发环境是2013,所以要装vs2013redist.

(3)最后要注意将 msvcp120.dll,msvcp120d.dll,msvcr120.dll,msvcr120d.dll,vccorlib120.dll,vccorlib120d.dll放到C:\Windows\SysWOW64目录下,32位的目标机器则放到win32下面。

如果有更好的办法,请告诉小弟。

时间: 2024-10-05 23:23:40

c#与c++交互的一些东西的相关文章

对象之间的交互

之前写过一篇随笔<剪刀剪纸>是给一些新同事讲面向对象时用的,当时就感觉有些不顺畅,不过用来给新同事入门足够了就没多想,最近看书时偶尔走神把这件事想起来了,顺便群里讨论时谈到聚合之间的方法调用,于是决定写一篇博客纠正一下那篇随笔里的问题. 开头先声明一下,以下只是个例子,只是用来说明对象间交互的解耦,怎么样交互我觉得更好,但是如果是真的要写一个剪刀剪纸的程序,之前随笔的做法并不一定就是不好的,有些耦合只是在需要解的时候才应该去解.另外,以下做法只是理想的做法,但是现实的项目总会有各种各样的妥协,

视觉交互

从来没有从来没有接触过电脑的我,在选择计算机之前根本不知道视觉交互是什么东西,更不知的怎么用,现在我接触了视觉交互,感觉视觉交互真的是很神奇的东西,特别是自己常常在手机上从来没有的ps,只知道它可以将图片p的很漂亮,现在自己学了ps,终于知道它是怎么出来的了.其实就是需要学习很多的工具,以及我们在做项目是更快的快捷键,例如:选框工具(M)按住shift,渐变工具(G),平滑工具,吸管工具,套索工具,沿着边缘择选区用磁性套索工具,ESC全部删除(如果选择磁性套索又不想要),按住shift会约束多边

新颖交互形式的H5案例浅析(技术分析)

最近我们前端这边搜集了50个比较优秀的H5. 那我这边呢,根据技术的分类,找出其中十个有代表性的案例,给大家解析一下他们技术的实现方案. 设计师也可以根据技术实现作为你们提供的素材参考 因为我主要是对技术分类的介绍,所以只取了不同技术实现的案例,同一种技术实现的不同的设计风格我就不列举出来了. 首先稍微提一下,其中包含的技术主要分为:createjs/thresjs/video内联播放/ 首先第一个呢,是之前腾讯爸爸出品的腾讯动漫的一个APP宣传的H5,这个H5是由腾讯内的TGideas团队完成

Spring shiro学习(一)

先转一下开涛大神的shiro基础,讲的很好 1.1  简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的Shiro就足够了.对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了. 本教程只介绍基本的Shiro使用,不会过多分析源码等,重在使用. Shiro可以非常容易的

Xamarin入门浅析

1. 安装 1) 使用标准安装流程(JDK1.6 -> Android SDK -> NDK -> Xamarin Studio -> Xamarin Visual Studio) 2) Android SDK Manager更改源,可时刻保持最新,一个镜像源地址:mirrors.neusoft.edu.cn:ubuntu.buct.cn:Port: 80,Android SDK的目录结构介绍,Android的一些相关资源 (http://ubuntu.buct.edu.cn/an

Shiro 入门

Apache Shiro(http://shiro.apache.org/) 是 Java 的一个安全(权限)框架. Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境. Shiro 可以完成:认证.授权.加密.会话管理.与Web 集成.缓存等. 主要类介绍 Authentication:身份认证/登录,验证用户是不是拥有相应的身份:1. Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用户是

shiro简介

简介: Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的Shiro就足够了.对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了. Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spri

shiro-简介

简介: Apache Shiro 是Java的一个安全(权限)框架. Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境. Shiro可以完成:认证.授权.加密.会话管理.与Web集成.缓存等. 下载Shiro :http://shiro.apache.org/ 工程简介: ?Authentication:身份认证/登录,验证用户是不是拥有相应的身份:?Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用

Apache Shiro学习笔记

鲁春利的工作笔记,好记性不如烂笔头 官网地址:http://shiro.apache.org/ 主要功能包括: Authentication:身份认证/登录,验证用户是不是拥有相应的身份:Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用户是否能做事情:常见的如:验证某个用户是否拥有某个角色. Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中:会话可以是普通JavaSE环境的,也可以是如Web环境