最近完成了一个小项目的开发,在开发中遇到了一些问题,我感觉这些问题其他人在开发的时候也会遇到,所以我在这边总结一下我遇到的问题,并给出我的方法,希望能帮到各位。
C#引用C++
我们在开发项目的时候,经常会遇到需要调用C++项目或者库的情况,特别是集成了一些算法的项目(因为C++对内存的使用更加精准,效率更高,所以一般算法都会用C++来实现)。这个时候我们需要将C++项目封装成C#能调用的形式。
动态库/静态库
静态库
C#不能直接调用C++静态库,所以需要对C++编译的静态库做一些处理,一般都是将静态库的相关文件再用C++封装一下,编译成动态库,然后给供C#项目调用。
动态库
一般C++编译出来的动态库不能直接引用,我们需要在C#中导出C++动态库的方法
C++中的代码
__declspec(dllexport) void SpectralTrueGet(double *SpectralIn, double *SpectralDarkIn, double *SpectralRefenceIn, int iLength, double *SpectralTrueOut);
C#中的代码
[DllImport(@"SugerCore.dll", EntryPoint = "SpectralTrueGet", CallingConvention = CallingConvention.Cdecl)]
public extern static void SpectralTrueGet(double[] SpectralIn, double[] SpectralDarkIn, double[] SpectralRefenceIn, int iLength, double[] SpectralTrueOut);
这里我们需要将C++中的一些变量进行本土化,比如double类型的指针,如果他们表示的是double数组那么就需要转换成double[],但是如果表示的就是一个double值,那么就需要转换成ref double,这些需要根据C++中实际情况来判断。
unsafe和fixed关键字的应用
unsafe
不安全代码,要使用这个关键字,我们需要一些配置,如下
- 打开项目属性
- 在项目属性中,有关于项目生成的配置
- 在这个配置界面中找到,常规->允许不安全代码,勾上这个选项
使用unsafe,主要是为了让C#项目中能使用指针,C#一般情况下是不支持指针的(不能主动创建内存空间)
fixed
fixed需要在unsafe的作用域之下,如下
unsafe
{
int[] array = new int[10];
for (int i = 0; i < array.Length; i++)
{
array[i] = i;
}
fixed (int* p = array)
{
for (int i = 0; i < array.Length; i++)
{
System.Console.WriteLine(p[i]);
}
}
}
这里我们需要使用fixed来规范指针的定义,它的意思是让p固定指向数组array,不允许改动。因为C#的自动垃圾回收机制会允许已经分配的内存在运行时进行位置调整,如果那样,p可能一开始指的是array,但后来array的位置被调整到别的位置后,p指向的就不是array了。所以要加一个fixed关键字,把它定在那里一动不动,之后的操作才有保障。
Path类的使用
我们在开发上位机项目的时候经常会遇到这种地址拼接的情况,比如我们需要Create一个文件,但是文件所在的文件夹地址和文件名不在同一个地方定义;再比如我们获取到了一个位置的文件全地址,这个时候我们想要获取它的文件名。
地址拼接
string path1 = @"D:\temp";
string path2 = "result.txt";
string newPath = Path.Combine(path1, path2);
文件名获取
string fullPath = @"\WebSite1\Default.aspx";
string filename = System.IO.Path.GetFileName(fullPath);//文件名 “Default.aspx”
string extension = System.IO.Path.GetExtension(fullPath);//扩展名 “.aspx”
string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(fullPath);// 没有扩展名的文件名 “Default”
写在结尾
其实C#开发上位机还是简单的,框架和模组我们都可以选择通过Nuget导入,这是好处的同时也是我们的弊端,容易被替代,所以我觉得做C#开发的人,要把自己工作的重心放在业务的抽象能力,和框架的梳理能力,后面我会把我在项目中使用的设计模式和为什么使用这种设计模式写出来,希望大家都能学习到东西。天道酬勤,与君共勉。