由于项目需要在C#中调用opencv的函数处理图像,而暂时没时间了解CLR/C++,所以就采用封装API的方式调用,使用的IDE是VS2015,记录过程如下:
在VS2015新建visual C++项目——Win32项目——应用程序类型DLL——完成,由于我的opencv在64位下配置,所以解决方案切换为x64、release(此模式下会省掉调试信息,适合最终发布的版本)。
解决方案名称与项目名称都为useopencv,在项目中创建自己的头文件useopencv.h,将要打包的函数在此声明,如:
extern "C" __declspec(dllexport)void __stdcall use_opencv(const char* add);
打开stdafx.h,将useopencv.h与opencv的头文件放到stdafx.h里面。再将函数的实现部分复制到useopencv.cpp,此处以打开一张图片为例:
void __stdcall use_opencv(const char* add) {
using namespace cv;
Mat src = imread(add);
imshow("src", src);
waitKey(0);
return;
}
为进一步保证函数名不会被修饰,在项目——源文件——添加——新建项——代码——模块定义文件(.def),添加Source.def,并对要导出的函数进行编号,如:
LIBRARY "useopencv.dll"
EXPORTS
use_opencv @ 1
之后就可以生成解决方案了,在项目的\x64\release里面就能看到useopencv.dll了
新建项目——c#控制台程序,创建好后引入这样一个名字空间:
using System.Runtime.InteropServices;
然后项目右键——属性——生成——目标平台——x64(这一步非常关键,VS中解决方案的配置与项目的配置不一定一样!)
通常每一个函数都要这样的语句单独导入一次,DllImport还有一些可设定的参数,比如调用方式stdcal、Cdecl这些,这里就直接用默认值了。注意在C#中与const char*对应的是System.String类。
[DllImportAttribute(@"E:\VS项目\useopencv\x64\Release\useopencv.dll")]
public extern static void use_opencv(System.String add);
直接调用函数即可,另外,导入的函数也可以有参数,只是得匹配好c++与c#中的类型,具体如何对应很多文章上有。
use_opencv("D:/opencvimage/learn/_1.jpg");