1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Rustのデータ付きenumをSwift側で使いたい

Last updated at Posted at 2023-02-19

C言語と互換性があれば、rustのプログラムをSwiftのプログラムとlinkすることができます。しかし、enumの各Variantがデータを持っていた場合は、どうしますか? C言語ではenumの各Variantにデータが存在しません。この記事では、そのlink方法を紹介します。

サンプルコードはこちら

rustで書かれたenumを用意しましょう。

#[repr(C)]
pub enum NiwakaEnum {
    Variant1(i32, u32),
    Variant2,
}

これとメモリの配置が等価な表現をSwiftで用意するには、

//これはヘッダーファイルです。
typedef enum NiwakaEnumTag { Variant1, Variant2} NiwakaEnumTag;
typedef struct NiwakaVariant1Fields{
    int32_t _0;
    uint32_t _1;
} NiwakaVariant1Fields;
union NiwakaEnumFields { NiwakaVariant1Fields Variant1;};
typedef struct NiwakaEnum { NiwakaEnumTag tag; union NiwakaEnumFields payload;} NiwakaEnum;

Swiftのstruct NiwakaEnumが、Rustのenum NiwakaEnumとメモリ表現が同じです。試しに、Rust側で用意した関数に、struct NiwakaEnumを渡してみましょう。

#[no_mangle]
pub extern "C" fn print_niwaka_enum(niwaka_enum: NiwakaEnum) {
    match niwaka_enum {
        NiwakaEnum::Variant1(value_i32, value_u32) => println!("NiwakaEnum::Variant1({}, {})", value_i32, value_u32),
        NiwakaEnum::Variant2 => println!("NiwakaEnum::Variant2")
    }
}

これをSwift側で(フォーマットツール適用してません。ベタ書きですみません。)

print_niwaka_enum(NiwakaEnum(tag: Variant1, payload: NiwakaEnumFields(Variant1: NiwakaVariant1Fields(_0: 10, _1: 100))))

実行結果は、

NiwakaEnum::Variant1(10, 100)

です。

なぜ同じなのか?

詳細は、Enums With FieldsUsing Imported C Structs and Unions in Swiftを読みましょう。

参考

Enums With Fields
Using Imported C Structs and Unions in Swift

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?