#struct #translate #ffi #proc-macro

translator

这是一个过程宏,它将在编译时将您的repr-C结构体转换为C++、Python和C#,以帮助编写FFI库。

5个不稳定版本

使用旧的Rust 2015

0.3.1 2022年11月11日
0.3.0 2018年8月3日
0.2.1 2018年5月31日
0.1.1 2018年5月30日
0.1.0 2018年5月30日

#691 in 过程宏

MIT 许可证

30KB
486

翻译器

翻译器是一个Rust过程宏,它将Rust结构体转换为其他语言,以便在Rust FFI(或你希望以其他方式使用它们的情况下)中公开。那些不是 [repr(C)] 的结构体将被忽略。结构体会被转换为

  • Python
  • C++
  • C#

这个宏不是万能的,但它将(希望)极大地减少创建Rust库供其他语言使用的成本

使用

输入

假设你想翻译以下结构体

#[repr(C)]
#[derive(Clone, Copy)]
pub struct SomeStruct {
    //pub raw_message: [i16;5],
    pub foo: i32,
    pub bar: Baz,
    pub foobar: [u8;5]
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct Baz {
    pub bob: f32
}

你需要添加Translator宏和Translator到派生中。你还需要将“魔法结构体”添加到结构体声明的末尾。它看起来像这样

#[macro_use]
extern crate translator;

#[repr(C)]
#[derive(Clone, Copy, Translate)]
pub struct SomeStruct {
    //pub raw_message: [i16;5],
    pub foo: i32,
    pub bar: Baz,
    pub foobar: [u8;5]
}

#[repr(C)]
#[derive(Clone, Copy, Translate)]
pub struct Baz {
    pub bob: f32
}

#[derive(Translate)]
struct __FinalizeTranslatorStruct__{}

当你编译时,在“target”文件夹中会创建一个名为“TranslateOutput”的新文件夹,其中包含3个文件(每个语言一个),内容如下

c++

typedef struct SomeStructTag {
	int32_t foo;
	Baz bar;
	uint8_t foobar[5];
} SomeStruct;

typedef struct BazTag {
	float bob;
} Baz;

Python

class SomeStruct(Structure):
        _fields_ = [
        ("foo", c_int),
        ("bar", Baz),
        ("foobar", c_ubyte * 5),
        ]

class Baz(Structure):
        _fields_ = [
        ("bob", c_float),
        ]

C#

[StructLayout(LayoutKind.Sequential)]
public struct SomeStruct
{
    public int foo;
    public Baz bar;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
    public byte[] foobar;
}

[StructLayout(LayoutKind.Sequential)]
public struct Baz
{
    public float bob;
}

Mastodon

依赖关系

~2MB
~47K SLoC