19. rust中进行Windows系统开发

一、前言

作为系统级语言,rust可以很容易的和C++一样进行系统级编程,但实际操作后我相信你会遇到相当多的问题。

比如以本文要介绍的windows系统编程为例,由于windows系统底层使用的C/C++语言,导致其大量api的参数都是指针,而rust作为一门安全性极高的语言,对于指针的操作会有极大的限制。

其次就是字符串的问题,windows系统大量api都使用的宽窄字符集,而rust默认使用的是UTF-8编码,这之间就涉及编码转换的问题。

对编码不了解的可以参考这篇文章:编码

而本文就将针对这些问题展开,让你能快速熟悉在rust中使用win api的基本过程。

二、指针

首先第一个麻烦就是指针,rust中也是存在像C/C++那样的指针的,只不过需要使用as关键字进行显示的强制转换:

image-20240115165444512

在rust中,指针和变量一样分为两种类型,第一种是不可变指针,也就是*const,另一种为可变指针,为*mut,其后再跟实际的指针类型,比如这里为i32类型。

注意这里的可变与不可变针对的都是变量papb指向变量的值,比如pa由于是不可变的,所以你不能更改它所保存的a地址上的值,而pb由于是可变的,那么可以修改它所指向的b地址上的值:

image-20240115170043853

设置指针的值同样是通过*pa这样的形式实现的,但由于指针操作是一件非常不安全的事情,所以你必须要将其包裹在unsafe中才能编译通过。

从上图就能看出两者的区别,因为pa指向的不可变值,所以这里就无法为其赋值,但此时pb却是可以的。

如果你希望修改papb本身的值,也就是指针本身所存储的地址,换一个其它变量的地址,那么只需要像普通变量那样在let后面添加一个mut关键字即可:

let mut pa=&a as *const i32;
pa=&b as *const i32 //此时就能修改其上存储的地址

除了这些基本的,标准库也专门提供了一个指针库,比如在C/C++中最常见的null指针,就可以通过下面的代码获取:

image-20240115170808652

看上去这种写法似乎有些奇怪,但实际上就是两个函数而已,第一个为null函数,也就是获取一个不可变的*const指针,而第二个为null_mut函数,用于获取可变的*mut指针。

只不过由于指针也需要具体的类型,所以这里是通过模板的语法在函数名后面添加::<i32>的方式来指明它的类型为i32

这里需要这样写的因为是我们用不上它们,但在实际写代码过程中,一旦我们用于将其填入某个函数参数中,而函数参数本身已经有类型了,所以即使不写::<>指明类型,rust编译器也能自动推断出其类型。

除此之外,正如前面所说,Windows系统底层使用的C/C++语言实现,所以自然就不可避免的在某些时候需要用到C/C++中的数据类型。

比如最常见的void类型指针,在后面的win api编程中你会大量的遇到,而rust本身是没有void类型的。

不过rust同样提供了库ffi来解决这个问题:

image-20240115171742701

ffi库中包含了所有C/C++中的基本数据类型,可以直接使用。

比如我这里想要获取一个c_void类型的指针,就需要先将其引用类型转换为指针,然后再进一步转换为c_void类型的指针,这里用as连续转换了两次,所以看起来有点长,分开看即可。

三、windows

rust中的指针有了前面的基础基本也就够了,字符串的问题放在后面,这里先来聊聊如何在rust中使用win api。

想要在rust中使用win api目前主要有三个crate:

  • winapi:网上资料较多,但已经有很久没更新过了,目前用的人最多
  • windows:官网维护、使用rust将api封装了一层,使用更简洁,积极更新中
  • windows-sys:官方维护、几乎未封装,完全原生的api,积极更新中

如果你现在在网上搜索相关的资料,大部分应该都是使用的winapi这个crate,虽然也能用,但其数年不更新让我感觉还是有点不太稳当。

至于windows-sys,基本就是完全原生的api,和你在C/C++中写的代码差不多,但又由于有rust的安全机制在,导致其用起来相当的麻烦。

所以我一般习惯于使用windows,该库是官方维护的库、持续更新,同时又用rust将其封装了一层,用起来相对要简洁的多。

除了在配置文件的依赖项中添加:

windows = "0.52.0"

你也可以直接运行命令cargo add windows下载最新的版本。

不过上面两种方式都不推荐,最好是直接复制官方提供的代码模板到配置文件中:

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux