C#上位机开发常遇问题

本文介绍了C#在上位机开发中如何引用C++动态库和静态库,详细阐述了动态库和静态库的区别以及转换方法。同时,探讨了unsafe和fixed关键字在C#中的使用,用于处理C++中的指针操作。此外,还提及了Path类在文件路径操作中的常见应用,如文件名和扩展名的获取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


最近完成了一个小项目的开发,在开发中遇到了一些问题,我感觉这些问题其他人在开发的时候也会遇到,所以我在这边总结一下我遇到的问题,并给出我的方法,希望能帮到各位。

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

不安全代码,要使用这个关键字,我们需要一些配置,如下

  1. 打开项目属性
    在这里插入图片描述
  2. 在项目属性中,有关于项目生成的配置
    在这里插入图片描述
  3. 在这个配置界面中找到,常规->允许不安全代码,勾上这个选项
    在这里插入图片描述
    使用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#开发的人,要把自己工作的重心放在业务的抽象能力,和框架的梳理能力,后面我会把我在项目中使用的设计模式和为什么使用这种设计模式写出来,希望大家都能学习到东西。天道酬勤,与君共勉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值