Corrode可以把C源代码转换为等价的Rust代码。它使用haskell开发,项目地址:https://github.com/jameysharp/corrode。
在Ubuntu上安装测试Corrode
安装ghc和cabal:
# https://www.haskell.org/downloads/linux
$ sudo apt-get update
$ sudo apt-get install -y software-properties-common
$ sudo add-apt-repository -y ppa:hvr/ghc
$ sudo apt-get update
$ sudo apt-get install -y cabal-install-1.22 ghc-7.10.3
$ cat >> ~/.bashrc <<EOF
> export PATH="\$HOME/.cabal/bin:/opt/cabal/1.22/bin:/opt/ghc/7.10.3/bin:\$PATH"
> EOF
$ export PATH=~/.cabal/bin:/opt/cabal/1.22/bin:/opt/ghc/7.10.3/bin:$PATH
下载corrode源代码:
$ git clone https://github.com/jameysharp/corrode
编译安装:
$ cd corrode
$ cabal update
$ cabal install happy
$ cabal install alex
$ cabal install
corrode安装路径~/.cabal/bin。
运行corrode,它可接受gcc的任意选项。
$ corrode -Wall filename.c -I/usr/local/include -lm
C代码:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
double randn(double mu, double sigma)
{
double U1, U2, W, mult;
static double X1, X2;
static int call = 0;
if (call == 1)
{
call = !call;
return (mu + sigma * (double) X2);
}
do
{
U1 = -1 + ((double) rand () / RAND_MAX) * 2;
U2 = -1 + ((double) rand () / RAND_MAX) * 2;
W = pow (U1, 2) + pow (U2, 2);
}
while (W >= 1 || W == 0);
mult = sqrt ((-2 * log (W)) / W);
X1 = U1 * mult;
X2 = U2 * mult;
call = !call;
return (mu + sigma * (double) X1);
}
int main()
{
printf("%f\n", randn(0, 1)); // mu = 0 & sigma = 1 是标准正态分布
printf("%f\n", randn(3, 2.5));
return 0;
}
上面的C代码使用corrode转换生成的rust代码:
extern {
fn log(__x : f64) -> f64;
fn pow(__x : f64, __y : f64) -> f64;
fn printf(__format : *const u8, ...) -> i32;
fn rand() -> i32;
fn sqrt(__x : f64) -> f64;
}
#[no_mangle]
pub unsafe extern fn randn(mut mu : f64, mut sigma : f64) -> f64 {
let mut U1 : f64;
let mut U2 : f64;
let mut W : f64;
let mut mult : f64;
static mut X1 : f64 = 0f64;
static mut X2 : f64 = 0f64;
static mut call : i32 = 0i32;
if call == 1i32 {
call = (call == 0) as (i32);
return mu + sigma * X2 as (f64);
}
loop {
{
U1 = -1i32 as (f64) + rand(
) as (f64) / 2147483647i32 as (f64) * 2i32 as (f64);
U2 = -1i32 as (f64) + rand(
) as (f64) / 2147483647i32 as (f64) * 2i32 as (f64);
W = pow(U1,2i32 as (f64)) + pow(U2,2i32 as (f64));
}
if !(W >= 1i32 as (f64) || W == 0i32 as (f64)) {
break;
}
}
mult = sqrt(-2i32 as (f64) * log(W) / W);
X1 = U1 * mult;
X2 = U2 * mult;
call = (call == 0) as (i32);
mu + sigma * X1 as (f64)
}
fn main() {
let ret = unsafe { _c_main() };
std::process::exit(ret);
}
#[no_mangle]
pub unsafe extern fn _c_main() -> i32 {
printf(b"%f\n\0".as_ptr(),randn(0i32 as (f64),1i32 as (f64)));
printf(b"%f\n\0".as_ptr(),randn(3i32 as (f64),2.5f64));
0i32
}