C#调用C++的dll及MATLAB的dll的方法(二)

来源:互联网 发布:java程序员面试问题 编辑:程序博客网 时间:2024/06/05 17:30

在上一篇博客中我们介绍了一下如何利用C#调用C++封装的托管代码,这一篇我们介绍一下如何用C#调用MATLAB封装的代码。

MATLAB的程序完成的功能主要是人脸对齐和图像的crop操作,以便后面送给分类器进行人脸属性的预测。本来想着用C++重新实现一次,这样就可以按照上面的C#调用C++的dll方式再做一次。但是呢,无论我采用什么方式出来的结果总是和MATLAB的结果不一样。我训练模型所用的训练数据和测试数据全部用的都是MATLAB得到的结果,因此别无选择了,只能还用MATLAB的程序,然后就想到了用C#调用MATLAB的dll。其实我试过先把MATLAB包装dll让C++调用,再用C#调用C++,但是失败了。。。因为在vs2013的C++程序里调用MATLAB的dll还是要配置很多东西的,包括一些依赖的dll和lib,因此当我把他们包装起来送给C#的时候总是提示缺少依赖的dll,然后我就无奈了,然后我就决定还是用C#直接调用MATLAB吧。事实证明,C#直接调用MATLAB其实更方便。


前面一篇博客提到我的环境是win7 64位+vs2013+MATLAB2015。坑就坑在MATLAB版本太新,网上所有的资料显示的都是MATLAB2012,2010,甚至还有2005!!!他们提到的创建MATLAB的.Net工程,原谅臣妾真的找不到在哪里啊。。。所以后来干脆瞎鼓捣吧。好在凭借着不笨的脑子,搞出来了!
貌似MATLAB一直都是支持创建.Net工程的,就是为了很多人可能会用到跨语言和平台进行调用。而且,不同的语言有不同的优势,虽然MATLAB大多数功能C++可以实现,甚至如果是图像处理相关的操作,opencv基本可以搞定。但是从写代码的难易来讲,我觉得MATLAB语言更好写一点,对于矩阵(图像也是矩阵的存储方式)来说更是优化了许多操作,各种对矩阵的操作也很好写。因此,在C#调用MATLAB的dll不太麻烦的情况下,是比较建议用MATLAB做的。当然,这个纯属个人观点。
如果要让C#调用MATLAB的dll,首先要生成C#认同的dll版本,这个生成的过程和C++差别挺大的,我不太清楚,C++可以用的dll和C#可以用的dll是不是相同的,不过有心的童鞋可以自己试试。

下面讲一下如何在MATLAB里面生成C#可以调用的dll。

首先,在MATLAB的命令窗口里输入deploytool,然后会弹出来一个小窗口让你选择你想做的任务:

如果我们想把m文件封装成dll的话,需要选第三个library compiler,虽然我也比较好奇为啥是library不是之前大家口中的.Net project。不过选这个就对了。然后就会出现下面的窗口:


然后在图中1的地方选一下.NetAssembly,这个就能和之前的资料对上了。然后2那里点“+”好选择你要封装的m文件,3是你封装后生成的dll的名字,4是在C#里你要调用MATLAB时需要创建的对象的类名,5是你要调用的函数。好了,把这几个填好之后,点击右上角的“√”,等大概一分钟就可以生成dll文件啦。


然后你会看到在当前MATLAB的目录下会多出来一个文件夹,名字是上图3中你填写的名字,打开这个文件夹可以看到有好几个文件:


打开第二文件夹,里面的dll就是我们需要的。


好啦,至此MATLAB封装dll就大功告成了,是不是比C++要方便一些。接下来,我们看看如何在C#里使用这个dll。


还是和C++的dll类似,我们需要把这dll拷贝到C#的工程目录下,同时还要拷贝一份MWArray的dll,这个是C#专门针对调用MATLAB语言所设计的数据类型,如果不添加这个dll,那么在C#是无法调用MATLAB的。


与C#调用C++的dll步骤类似,我们仍旧需要将这两个dll同时拷贝到C#的exe所在的文件夹,我这里是release any cpu的配置模式,那么就将其拷贝到工程目录下Bin目录里的release文件夹下:


好,此时准备工作就做好啦!有些童鞋可能比较好奇这个MWArray.dll是从哪儿冒出来的,怎么好像之前没见过呀。如果你装了MATLAB的话,那么这个dll可以在matl的安装目录里找到,路径如下:


好嘞!现在可以讲讲怎么在C#里面调用MATLAB的dll。首先,我们在C#的项目“引用”那里将刚才的MATLAB封装好的dll和MWArray.dll引用进来。同时,需要在头文件那里添加:


这里面第一个其实是在C#调用C++那里不是把C#里的string转为sbyte*嘛,那会除了提示不安全代码外,还需要加上第一个using才可以完成类型转换。第二行和第三行是使用MATLAB的dll所必需的,只有当你将MWArray.dll引用进来以后,这两个才可以using,否则会提示你是无效的using或者这个命名空间不存在之类的。


然后是代码里如何调用MATLAB的封装的函数:


这个地方我也纠结了很久,又是类型转换的问题。MATLAB的调用函数方式和C++略有不同,首先会有一个int的参数,你就写1就行,我也不太清楚是干啥的。另外,它是把返回值用“ref”关键字表示出来,然后后面才是输入参数,输入参数只接受一个为MWArray的类型的,这个是一个数组,你可以把你所有需要输入的参数放到这个数组里,然后传过去。输出同样是一个数组,可以输出多个值,你需要哪个就用获取数组元素的方式获取就好了。就是string要想作为输入参数传进去,需要经过上图那么折腾一圈才可以。


至此,大功告成!!!




1 0
原创粉丝点击