使用Rust + Electron開發跨平臺桌面應用 ( 一 )

前言

近段時間學習了Rust,一直想着作點什麼東西深刻學習,由於是剛學習,不少地方都不熟悉,因此也就不能拿它來作編譯器這些,至於web開發,實際上我並不建議拿這個來學習一門語言,大概有幾個方面,一是web開發的套路無非也就那麼幾個,對學習一門語言並不會有多大的幫助。二是web開發大多已經被封裝了不少東西,對學習語言自己其實不利,真的要深刻學習的話仍是建議從語言自己出發,儘可能不要用封裝好的東西,固然,標準庫除外。html

爲何是Rust + Electron

緣由其實很簡單,我不想作太複雜的東西,由於大部分的精力仍是要放在工做上,其次是但願作一個我平常能用的東西,固然如今還沒想好,多是個音樂播放器,也多是個天氣展現的app,這樣我就能夠天天使用了,這也會更有動力促使我開發好它。node

Rust 和 Electron 想必就不用我多介紹了吧,至於爲何是這個組合能夠查看知乎的這個問題,我贊同的是的方案是python

使用 C/Cpp/Rust 開發的核心 + Electron / Qt 開發界面

本期目標

本期的目標很是簡單,將Rust 和 Electron結合起來,使用Rust獲取電腦cpu核數,Electron將數據繪製在界面上展現。git

初始化Electron項目

Electron項目的初始化我用的工具是electron-forge,首先咱們按照electron-forge的官網介紹來github

npm install -g electron-forge

electron-forge init my-new-project

cd my-new-project

electron-forge start

解釋一下,首先咱們要安裝electron-forge,這是一個腳手架工具,相似於Vue-cli。
而後咱們初始化一個項目,項目名稱爲my-new-project。web

須要注意的是這初始化的過程當中electron-forge會構建package.json, 而後下載依賴,我第一次下載依賴的時候卡在了electron-runtime,第二次重試的時候就行了。npm

第二個是electron-forge中的依賴會對Python版本有要求,只能要求Python2,這裏要注意的一點是,我十分不建議使用pyenv來控制Python版本,會出現如下錯誤,個人解決方式是使用virtualenv新建一個Python2 的環境。json

Fatal Python error: PyThreadState_Get: no current thread

如今咱們來看一下項目結構app

clipboard.png

整個項目結構很是簡單,src中是咱們的源文件,index.html是界面文件,index.js是界面邏輯文件,你們打開index.js就能夠看到一段自動生成的代碼,主要是建立了一個app,以及監聽app的活動,須要注意到的是其中對mac的處理。electron

app.on('window-all-closed', () => {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

好了,如今讓咱們把項目跑起來,在項目目錄下執行electron-forge start命令,稍等一會咱們就能夠看到界面運行起來了

clipboard.png

初始化Rust項目

在開發以前咱們要知道,JS是沒法直接運行Rust的,就像JS沒法直接運行C++同樣。因此咱們須要將Rust打包成Node模塊提供給JS進行調用。因此咱們會使用neon來作到這件事,neon的github地址在這裏

首先咱們須要安裝neon,注意,neon對python版本也是有要求的,若是你是mac,python版本必需要是Python2.7,不支持Python3,一樣,這裏也會出現上面說過的no current thread問題,因此咱們在開發時最好用virtualenv新建一個Python2的環境。

安裝完neon以後咱們執行neon new thread-count,新建一個項目。看一下項目結構

clipboard.png

lib是咱們最終的導出文件,提供給electron進行調用,native下則是咱們的rust代碼,注意,這裏的入口文件是native/src/lib.rs,由於咱們創建的是一個庫而不是一個可執行的應用程序。
讓咱們先編譯項目,在文件目錄下執行neon build --release命令。

讓咱們進入終端調用一下項目試試:

clipboard.png

成功!到如今咱們就成功的將rust寫的代碼封裝成node庫,使得JS能夠進行調用了,接下來咱們回到上面說過的,將rust的功能更改成獲取CPU核數,而後將它封裝成一個函數並進行導出。

首先咱們要修改Cargo.toml,在[dependencies]下增長一個num_cpus = "1.4.0"的依賴項,
而後修改native/src/lib.rs文件以下

#[macro_use]
extern crate neon;

use neon::prelude::*;

fn thread_count(mut cx: FunctionContext) -> JsResult<JsNumber> {
    Ok(cx.number(num_cpus::get() as f64))
}

register_module!(mut cx, {
    cx.export_function("thread_count", thread_count)
});

修改lib/index.js以下:

var addon = require('../native');

module.exports = addon.thread_count;

而後咱們再進行編譯,執行neon build --release命令,而後再進入終端調用這個函數試試

clipboard.png

成功啦,至此,咱們就成功的將rust代碼封裝給JS進行了調用。須要注意的是編譯rust的node版本須要與運行electron的node版本一致,不然會出現沒法調用的狀況。好了,到此第一期就結束了,代碼我會抽空整理到github,以供有須要的同窗查看。

效果

最後看一下效果圖吧

clipboard.png

ps: 如今Rust的各項工具和庫都不是很成熟,因此你們再實踐過程當中會遇到各類問題,均可以評論到下面你們一塊兒討論。

相關文章
相關標籤/搜索