C#调用C++生成的.dll
1.C++生成.dll动态链接库
1.打开需要调用的C++项目
点项目中的sln文件打开
2.右击项目名称 -> 属性
3.选择 常规 -》 配置类型 -》 动态库
4.应用或确定,然后右击项目名称,选择生成或者重新生成
出现如下输出就是成功了
到其中路径下找到 .dll 动态链接库
2.C#调用DLL
1.C#环境
VS安装一下.NET环境就可以了
2.项目配置
1.创建一个新的C#项目,选择控制台应用
2.选择要运行的环境 Debug 还是 Release ,以及平台
这里选了Debug 和 Any CPU
然后打开.cs 文件点击一下 启动 运行一下生成解决方案的文件夹如下
启动什么配置就生成对应的解决方案文件(这里我两个都运行过)
3.然后将上面 1.C++ 生成.dll动态链接库 中最后生成的.dll文件复制到该文件夹中
并且由于我的C++项目调用了python代码,其中的PyC文件夹就是存放了 .dll 要调用的python代码以及模型
images和out文件夹只是项目需要自己加进去的
4.回到VS中,右击项目名称 -》 属性
5.取消勾选首选32位,勾选允许不安全代码(因为我们代码中用到了指针)
并保存
3.C#代码及运行
在.cs中编写C#代码
C#调用DLL代码样例如下
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace CSharpBitmapAndCPPOpencv
{
class Program
{
[DllImport("AngleDetect.dll", CallingConvention = CallingConvention.Cdecl)]
/*
调用dll的函数
Parameter: (其中注释掉的为删除的参数)
1. imgPath:传入图像文件夹
2. outPath:传出图像文件夹
3. max_angle:传出相似度最高品牌条形码号
4. flag:相关传送标识符
flag[0] = 0 表示需要打开python解析器; flag[0] = 1 表示python解析器已打开;
flag[1] = 1 表示需要关闭python解析器; flag[1] = 0 表示python解析器未关闭;
flag[2] = 1 表示dll调用成功;
5. nResult:保存返回值
如果图片中没有超过 max_angle 的烟条,返回 0
否则返回超过 max_angle 的烟条个数,以及所以大于max_angle的角度
6. pdict_ptr:保存模型字典对象指针
*/
extern static unsafe void APIGetAngleFromCSharp(char[] imgPath, char[] outPath, int max_angle, int[] flag, ref byte* nResult, ref void* pdict_ptr);
static public void SendImgsToCPP()
{
string imgPathFolder = "./images/"; //传入图片的路径,相对路径
string outPathFolder = "./out/"; //保存图片的路径,相对路径
int max_angle = 10; //角度阈值
unsafe
{
DateTime now1 = DateTime.Now;
DirectoryInfo theFolder = new DirectoryInfo(imgPathFolder);
FileInfo[] thefileInfo = theFolder.GetFiles("*.*", SearchOption.TopDirectoryOnly);
foreach (FileInfo NextFile in thefileInfo) //遍历文件
{
string filename = Path.GetFileName(NextFile.FullName);
char[] imgPath = (NextFile.FullName).ToCharArray();
char[] outPath = (outPathFolder + filename).ToCharArray();
try
{
APIGetAngleFromCSharp(imgPath, outPath, max_angle, flag, ref nResult, ref pdict_ptr); //传输数据
byte* p = nResult;
int count = 0;
while (*p != '\0')
{
count++;
p++;
}
byte[] barr = new byte[count];
Marshal.Copy((IntPtr)nResult, barr, 0, count);
string ResultErrString = Encoding.UTF8.GetString(barr); //转换成字符串
Console.WriteLine(ResultErrString);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
static unsafe void* pdict_ptr = null;
static int[] flag = { 0, 0, 0 };
static unsafe byte* nResult = (byte*)Marshal.AllocHGlobal(sizeof(byte));
/// <summary>
/// 初始化导入模板
/// </summary>
public static unsafe void InitialDataSouce()
{
try
{
APIGetAngleFromCSharp(null, null, 0, flag, ref nResult, ref pdict_ptr); //导入模型
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static unsafe void FinalizePython()
{
try
{
//再次调用,释放python解析器
flag[1] = 1;
APIGetAngleFromCSharp(null, null, 0, flag, ref nResult, ref pdict_ptr);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
static void Main()
{
InitialDataSouce();
SendImgsToCPP();
FinalizePython(); //关闭python解析器
Console.WriteLine("END....");
Console.ReadKey();
}
}
}
点击启动即可开始运行代码
4.dll和exe路径
动态链接库和exe都在对应的Debug或Release文件夹中,保存好.cs后可以直接双击.exe运行
注意:如果后面在不修改接口的情况话更改python代码,直接到PyC文件夹下的.py文件夹下更改;如果修改C++代码,需要重新生成.dll动态链接库,然后替换掉该路径下的.dll