Rust初步(六):在C#中使用Rust組件

上一篇文章,咱們經過實例比較了一下C#和Rust的性能表現,應該說在Release模式下面,Rust進行計算密集型的運算仍是有些比較明顯的優點的。那麼,咱們有沒有可能,在C#中作一些快速應用開發,而一些核心的算法用Rust來實現呢?答案是能夠的。css

 

編寫Rust代碼

下面這段代碼,保存在lib.rs文件中html

use std::thread;

#[no_mangle]
pub extern fn process(){
    let handles :Vec<_> =(0..10).map(|_|{
        thread::spawn(||{
            let mut x= 0;
            for _ in (0..5_000_000){
                x+=1
            }
            x
        })
    }).collect();


    for h in handles{
        println!("Thread finished with count={}",h.join().map_err(|_| "Could not join a thread!").unwrap());
    }

    println!("done!");
}

 

這段代碼的幾個關鍵點在於linux

1.聲明爲pub,也就是說要讓外部能夠訪問到算法

2.聲明爲extern,意思應該也是說但願外部能夠訪問windows

3.添加一個標記 #[no_mangle],這個開關聽說是阻止編譯器在編譯的時候,重命名函數。我也還不是很理解,先照這麼作吧多線程

 

其餘部分就是標準的Rust代碼了函數

 

生成Rust的動態連接庫

默認狀況下,Rust編譯的庫叫作靜態連接庫,若是咱們須要編譯動態連接庫的話,須要在Cargo.toml文件中定義性能

image

而後,運行cargo build -- release命令生成動態連接庫(dll)ui

image

咱們在輸出目錄中,能夠看到一個countlib.dll 的動態連接庫文件spa

image

 

在C#中使用這個動態連接庫

你能夠將countlib.dll放在C#編譯輸出目錄的根目錄下面

using System;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;


namespace ConsoleApplication1
{
    class Program
    {

        [DllImport("countlib.dll",CallingConvention= CallingConvention.Cdecl)] public static extern void process();

        static void Main(string[] args)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();

            //Parallel.For(0, 10, i =>
            //{
            //    var x = 0;
            //    for (int j = 0;  j< 5000000; j++)
            //    {
            //        x += 1;
            //    }
            //    Console.WriteLine("線程:{0} 完成計數",Thread.CurrentThread.ManagedThreadId);
            //});

            process();//調用Rust裏面的程序process進行計算

            watch.Stop();
            Console.WriteLine("耗時:{0}秒", watch.Elapsed.TotalSeconds);
            Console.Read();
        }
    }

}
 
在Debug模式下面的耗時爲 0.002秒(提高太明顯了吧)
image
 
在Release模式下面的耗時爲0.002秒(基本上跟Debug模式不相上下,很神奇嗎)
image
 
那麼,這個性能表現,幾乎接近了直接使用Rust的性能,比原先用C#的方式提升了5倍。
 
如此說來,計算密集型(尤爲是須要用到多線程,多核)的任務,能夠用Rust來編寫,而後在C#中調用。
 
【特別注意】
cargo build默認狀況下會根據當前計算機的配置進行編譯,例如我是64位的計算機,那麼編譯出來的dll也是64位的,在C#中用的時候,就須要一樣設置爲64位,不然就會出現錯誤
image
 

那麼,cargo build是否能夠指定對應的平臺進行編譯呢?能夠經過指定 --target參數來實現,可用的值主要有

x86_64-pc-windows-gnu
i686-unknown-linux-gnu
x86_64-unknown-linux-gnu
詳細能夠參考 http://doc.crates.io/manifest.html
我用下面這樣用就能夠編譯一個通用的dll(既能用於32位,也能用於64位——採用WOW模式)
image
 
其實這個編譯選項,相似於咱們在Visual Studio中使用Any CPU進行編譯
image
相關文章
相關標籤/搜索