项目有个需求,要求实现Chrome的任务管理器模块。
进程管理相关的API跟操作系统强相关,所以这里使用node的原生扩展比较贴合实际。但是官方的NAPI需要配置node-gyp、写binding,还要到处查文档编写平台相关的编译参数。想想就头大...
好在系统调用为了方便扩展,都会有一版C兼容的API。这个时候rust的ffi模块就派上用场了。
前期准备
- rust -- windows请使用官网的exe安装,chocolate安装的rustup是gnu兼容的包,不利于对接win32 api
- napi-rs napi.rs/cn/docs/int…
起步阶段
通过上述步骤,一个脚手架工程就被快速创建好了。yarn build然后yarn test就可以快速验证代码了。
调试Rust代码 【VS Code】
每天上班写bug,怎么能不准备一手debug工具呢?JS调试的教程到处都有,这里单独说一下rust代码的调试配置。
- MacOS: CodeLLDB Extension ID:
vadimcn.vscode-lldb - Windows: C/C++ Extension ID:
ms-vscode.cpptools
扩展安装好之后,就可以配置VS Code了,
- 允许debug,添加
"debug.allowBreakpointsEverywhere": true到工程目录的.vscode/settings.json。或者在图形化设置中搜索everywhere - 编辑
.vscode/launch.json文件,生成调试配置。因为不同平台使用的API、依赖库迥异,所以这里拆成两个不同的入口文件target/debug/test和target/debug/test-win.exe来进行各自的调试。
{
"version": "0.2.0",
"configurations": [
{
"name": "(Windows) Launch",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceRoot}/target/debug/test_win.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
"preLaunchTask": "cargo build:test-win",
"environment": [],
"console": "internalConsole"
},
{
"name": "(OSX) Launch",
"type": "lldb",
"request": "launch",
"cargo": { // lldb扩展对rust有特殊的支持,这样就不必依赖外部的task来编译调试产物了
"args": ["build", "--bin=test"], // Cargo command line to build the debug target
},
"cwd": "${workspaceRoot}",
"console": "internalConsole"
}
]
}
.vscode/tasks.json每次调试前构建调试产物,task中的label必须跟configurations中的preLaunchTask完全一致
{
"version": "2.0.0",
"tasks": [
{
"label": "cargo build:test-win",
"type": "shell",
"command": "cargo",
"args": [
"build",
"--bin",
"test_win"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
配置完成后,在debug视图就可以选中对应的configuration进行调试了。
或者在编辑器窗口内,通过快速debug入口开始调试。
最终效果:
会用工具的程序员才是一个合格进化的好猩猩。
踩坑1:
如果mac下,DEBUG CONSOLE中一直提示错误码为-1的时候,可能是插件内置的lldb不兼容,需要重新配置CodeLLDB中lldb的选择。类似下面的输出:
Console is in 'commands' mode, prefix expressions with '?'.
Launching: /Users/xxx/rust-workspace/process-util/target/debug/test
Launched process 15288
Process exited with code -1.
具体步骤为CMD + SHIFT + P,选择LLDB: Use Alternated Backend...,然后输入lldb,会提示在.vscode/settings.json中添加lldb.library字段。示例如下:
{
"lldb.library": "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB"
}
踩坑2:
napi-rs会要求输入package name,npm对这里的要求比较宽松。但是rust中crate的名称不能有-(中划线 aka. dash)。所以package name最好不要使用-。可以使用napi rename来挽救一下,或者手动修改Cargo.toml等文件中的定义。