Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update csbindgen #40

Merged
merged 12 commits into from
Sep 7, 2023
Merged

Update csbindgen #40

merged 12 commits into from
Sep 7, 2023

Conversation

yamachu
Copy link
Owner

@yamachu yamachu commented Sep 5, 2023

csbindgen 1.7.5 をベースとした https://github.com/yamachu/csbindgen/tree/support-empty-emit-struct を使ってみたらいい感じに生成できた

yamachu/csbindgen@main...yamachu:csbindgen:support-empty-emit-struct

やったことと言えば

  • & の部分サポート (syn::Type::Reference)
  • Structの内部がprivateな型だったり非サポートな型だった場合に、無視して型だけ出力するフラグの追加

2つ目はだいぶお行儀の悪いやり方なので色々とダメそう…
& のサポートを万全にしたら本家PRでもいいし、VoicevoxCoreSharpの開発だけで言えばfork先を見続けるでもいいが、悩ましい


csbindgen 1.8.0 がリリースされて、& のサポートと、Contextとして使用するnon repr(C) のstructも出力できるようになったので、自前bindingが不要になった:clap:

@@ -21,149 +21,117 @@ internal static unsafe partial class CoreUnsafe



[DllImport(__DllName, EntryPoint = "initialize", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

globで全部持ってきたのでcompatible_engine周りが出てきてしまった
filterで対処する

[DllImport(__DllName, EntryPoint = "voicevox_open_jtalk_rc_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern VoicevoxResultCode voicevox_open_jtalk_rc_new(byte* open_jtalk_dic_dir, OpenJtalkRc** out_open_jtalk);

[DllImport(__DllName, EntryPoint = "voicevox_open_jtalk_rc_use_user_dict", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern VoicevoxResultCode voicevox_open_jtalk_rc_use_user_dict(OpenJtalkRc* open_jtalk, VoicevoxUserDict* user_dict);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&OpenJtalkRc みたいな感じで struct を受け取ろうとしていた箇所が生成されなくなってしまった

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

元々 OpenJtalkRc

pub struct OpenJtalkRc {
    open_jtalk: Arc<OpenJtalk>,
}

こんな感じの定義

cbindgenとかだと

typedef struct OpenJtalkRc OpenJtalkRc;

こんな感じで出力されている
FFIの際、中身をユーザに触らせないで、Pointerでやり取りするようなコードだと割りと出がちなやつ

csbindgenでも

    [StructLayout(LayoutKind.Sequential)]
    internal unsafe partial struct OpenJtalkRc
    {
    }

こんな空定義が吐き出せれば良かったりする…?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BoxやNonNullに対応してもらったお陰でだいぶ出力が増えたけど、こういう特殊なやつの対応はかなりユースケースが限られそう
一回forkリポジトリでEmitEmptyStructを許可するようなリストを読み取っていい感じにするのを試してみる

Comment on lines +162 to +172
/// <summary>ユーザー辞書に単語を追加する。 @param [in] ユーザー辞書 @param [in] word 追加する単語 @param [out] output_word_uuid 追加した単語のUUID @returns 結果コード # Safety @param user_dict は有効な :VoicevoxUserDict のポインタであること \\safety{ - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 - `word-&gt;surface`と`word-&gt;pronunciation`はヌル終端文字列を指し、かつ&lt;a href=\"#voicevox-core-safety\"&gt;読み込みについて有効&lt;/a&gt;でなければならない。 - `output_word_uuid`は&lt;a href=\"#voicevox-core-safety\"&gt;書き込みについて有効&lt;/a&gt;でなければならない。 }</summary>
[DllImport(__DllName, EntryPoint = "voicevox_user_dict_add_word", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern VoicevoxResultCode voicevox_user_dict_add_word(VoicevoxUserDict* user_dict, VoicevoxUserDictWord* word, void/* byte[] */* output_word_uuid);

/// <summary>ユーザー辞書の単語を更新する。 @param [in] user_dict ユーザー辞書 @param [in] word_uuid 更新する単語のUUID @param [in] word 新しい単語のデータ @returns 結果コード \\safety{ - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 - `word_uuid`は&lt;a href=\"#voicevox-core-safety\"&gt;読み込みについて有効&lt;/a&gt;でなければならない。 - `word-&gt;surface`と`word-&gt;pronunciation`はヌル終端文字列を指し、かつ&lt;a href=\"#voicevox-core-safety\"&gt;読み込みについて有効&lt;/a&gt;でなければならない。 }</summary>
[DllImport(__DllName, EntryPoint = "voicevox_user_dict_update_word", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern VoicevoxResultCode voicevox_user_dict_update_word(VoicevoxUserDict* user_dict, void/* byte[] */* word_uuid, VoicevoxUserDictWord* word);

/// <summary>ユーザー辞書から単語を削除する。 @param [in] user_dict ユーザー辞書 @param [in] word_uuid 削除する単語のUUID @returns 結果コード \\safety{ - `user_dict`は ::voicevox_user_dict_new で得たものでなければならず、また ::voicevox_user_dict_delete で解放されていてはいけない。 - `word_uuid`は&lt;a href=\"#voicevox-core-safety\"&gt;読み込みについて有効&lt;/a&gt;でなければならない。 }</summary>
[DllImport(__DllName, EntryPoint = "voicevox_user_dict_remove_word", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern VoicevoxResultCode voicevox_user_dict_remove_word(VoicevoxUserDict* user_dict, void/* byte[] */* word_uuid);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&[u8; 16] のような型指定にも対応したので生成されるようになった
元々 C# 側で自前定義していたのは

https://github.com/yamachu/VoicevoxCoreSharp/pull/40/files#diff-0121970d14c177b90e21118268940acfd9da1cf20945879dd6af89228e9a69dcL9-L16

binding/build.rs Outdated
Comment on lines 34 to 38
// 中身を C側 で触らない struct をここに列挙する
.rust_as_empty_struct("OpenJtalkRc")
.rust_as_empty_struct("VoicevoxSynthesizer")
.rust_as_empty_struct("VoicevoxUserDict")
.rust_as_empty_struct("VoicevoxVoiceModel")
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このアプローチはやっぱり微妙なので、voicevox_coreのc_api側で対処するのが良さそう

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VOICEVOX/voicevox_core#512
こういう経緯があったので、voicevox_core側も厳しいかなー

csbindgenでEmptyStructを吐き出すみたいな手段が取れないだろうか

@yamachu yamachu marked this pull request as ready for review September 7, 2023 11:16
@yamachu yamachu merged commit 6ad7307 into main Sep 7, 2023
@yamachu yamachu deleted the update-csbindgen branch September 7, 2023 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant