最近由于实习工作需要,要搞一些工程化的东西,为了计算效率等原因我们的算法是通过C++实现的,而最后的图像化软件界面是软工用C#完成的,因此需要提供我们C++的接口dll给他们软工使用C#进行调用
1.C++ dll生成
新建——项目——Win32控制台程序——然后取个名字——确定——下一步——选择DLL——勾选空白项目
参见:https://blog.csdn.net/qq_34097715/article/details/79540933
//add.h
#pragma once
#define DETECT_DLL_EXPORTS
#ifdef DETECT_DLL_EXPORTS
#define DETECT_DLL_API __declspec(dllexport)
#else
#define DETECT_DLL_API __declspec(dllimport)
#endif
#include <iostream>
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
DETECT_DLL_API void init(char *config_path);
DETECT_DLL_API double read(double *arrayHeight, int i, int j, int row, int col);
DETECT_DLL_API int add(int a,int b);
DETECT_DLL_API bool result(double height, double maxHeight, double minHeight);
#ifdef __cplusplus
}
#endif
其中C++中的头文件如上所示
//add.cpp
#include"add.h"
void init(char *config_path) {
getConfig(config_path);
}
double read(double *arrayHeight, int i, int j, int row, int col) {
return *(arrayHeight + i*col + j);
}
int add(int a,int b){
return a+b;
}
bool result(double height, double maxHeight, double minHeight)
{
bool result;
result = (height >= minHeight) && (height <= maxHeight);
return result;
}
C++代码实现在add.cpp中
2.C#调用dll
C#调用C++dll不需要C++的头文件和lib文件,只需要dll文件即可,将dll文件复制到C#工程运行exe文件所在的路径下
然后在C#中需要声明
[DllImport("ADD.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void init(string config_path);
[DllImport("ADD.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool result(double height, double maxHeight, double minHeight);
[DllImport("ADD.dll", CallingConvention = CallingConvention.StdCall)]
public static extern double read(double[,] arrayHeight, int i, int j, int row, int col);
[DllImport("ADD.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int add(int a,int b);
从声明中就可以看到如何使用这些函数
1、C++中的char *类型可以在C#中直接使用string类型传入,
2、C#的数组如double[,] arrayHeight可以直接在C++中使用double *类型接受,但是需要确定该数组的长宽,防止C++中指针越界
3、最值得注意的是,如果在C++中返回bool类型,需要添加[return: MarshalAs(UnmanagedType.I1)]这一行,否则在C#中会接受错误的数值
还有就是,在进行C#和C++ dll之间的传输的时候,不能传输对象等高级类型,容易出错,最好只使用数组和基础类型