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

C# API #559

Open
3 tasks done
qryxip opened this issue Aug 1, 2023 · 6 comments
Open
3 tasks done

C# API #559

qryxip opened this issue Aug 1, 2023 · 6 comments

Comments

@qryxip
Copy link
Member

qryxip commented Aug 1, 2023

内容

#550 の一つとして、managedでsafeなC#のAPIをこのリポジトリから提供します。

Pros 良くなる点

  • より大くの人に使って頂けることが期待できる
    • 饅頭遣いさんも確かC#使いだったはず
  • Unityでも直接利用することができるはず? (要調査)

Cons 悪くなる点

  • メンテコスト

実現方法

私の知る限り、PyO3のようなツールは存在しません。なのでC APIをベースにcsbindgenを使うことになるかと思います。以前ちゅうこさんが0.14に対して試してくれていて、そのメモをZennのスクラップにまとめてくれています。

Rust版voicevox_coreのC# Bindingを作るために調べる

ただ今わかっている限りでも、手で書く部分はPyO3以上にはなると思います。またasyncも持って来れないでしょう。

以下の記事はcsbindgenのリリースと共に公開されたものです。そしておそらく、csbindgenのスタンスはこのときから変化していないように見えます。C#メインのコードベースに少量のRustコードを入れることが想定されており、Rustのextern "C"からC#の[DllImport]の生成のみ行います。
(余談ですが、safe codeとunsafe codeの境界に関する考えかたとかがRustacean(Rust書き)とは随分違うなと感じました。まあC#の一般的なスタンスではないんでしょうけど)

neue cc - csbindgen - C#のためのネイティブコード呼び出し自動生成、或いはC#からのネイティブコード呼び出しの現代的手法について

csbindgenが対応しているRustの書き方ですが、cbindgenと比べて限定されています(具体的にはBoxとかNonNullを理解しません)。 C-unwindにも対応していないので、#541をやった日にはすべての関数を見失うでしょう。
(追記) extern "C-unwind"にしても多分大丈夫...だけどいささか雑では...?
https://github.com/Cysharp/csbindgen/blob/ffea1be84670e2fd8568cfeb67308b8193979fd6/csbindgen/src/parser.rs#L59
そのためちゅうこさんが最初やったように、cbindgenで生成したヘッダーからbindgenでまたRustのコードを生成し、それを読む形になると思います。

まあ下手なことをしなければ、VOICEVOX/csbindgenの誕生は抑えられるとは思います。

VOICEVOXのバージョン

N/A

OSの種類/ディストリ/バージョン

  • Windows
  • macOS
  • Linux

その他

@qryxip
Copy link
Member Author

qryxip commented Aug 1, 2023

CC: @shigobu, @yamachu

@yamachu
Copy link
Member

yamachu commented Aug 1, 2023

おっしゃるとおり、csbindgenをそのまま使う形だとBoxやNonNullを解釈できずに、ラップした型ではなくBoxと出力されてしまいます

https://github.com/yamachu/VoicevoxEngineSharp/blob/bfb31197b16a8ff4fe96567d916f91a06887c064/src/Core/src/Native/CoreUnmanaged.g.cs

enumが増える度に特別対応をする必要が出てきてはしまうのと、code docsが消えてしまうというデメリットはありますが、cbindgen => csbindgenの流れでコードを生成するのがいいのかなと思いました。
その流れで生成すると
https://github.com/yamachu/VoicevoxEngineSharp/blob/bcac60347d15ecf2ec38969d2805d3828f0c946b/src/Core/src/Native/CoreUnmanaged.g.cs
このぐらいのコードは出てくるようです。
これを元に、ユーザにunsafeな処理をさせないラッパーを実装することで一定の価値を提供できるのでないかと思いました。

またUnityで直接利用とのことですが、NativeLibraryを使用するのはiOSのリンク周りで何か踏みそうではありますが、可能そうではあります。

各言語のbindingをこのリポジトリで提供するのは確かにメンテコストがかかりそうではありますね…

@shigobu
Copy link
Contributor

shigobu commented Aug 2, 2023

cbindgen => csbindgenの流れでコードを生成するのがいいのかなと思いました。

この流れで使えるコードが生成できるのであれば、ちゅうこさんの意見に賛成です。
自動生成がうまく行った後で重要なのは、このコードをどのようにして隠すかですね。
せっかく、オブジェクト指向的なAPIになっているので、VoiceModelとかSynthesizerとかのクラスを作って、メンバメソッドとしてLoadVoiceModelとかAudioQueryとかを実装するのが良いのかなと思っています。

他に、

  • ターゲットフレームワークをどうするか
  • 提供(配布)方法をどうするか

が気になっています。

ターゲットフレームワークは、.NET Frameworkで使える.NET Standard 2.0がいいと思います。
https://learn.microsoft.com/ja-jp/dotnet/standard/net-standard?tabs=net-standard-2-0
提供方法は、DLLにしてcoreと一緒に配布するのが簡単かなと思います。

欲を言うと、NuGetに登録できると使う側が楽なんですけど、メンテナンスコストがかかるので微妙。やるなら、core本体もNuGetに登録してC#ラッパーはそれに依存するのが良いんだけど、さらにメンテコストかかることになる。coreはONNXにも依存しているし、依存関係のメンテも大変そう。

@qryxip
Copy link
Member Author

qryxip commented Aug 2, 2023

enumが増える度に特別対応をする必要が出てきてはしまうのと、code docsが消えてしまうというデメリットはありますが、

あーenum... そうでしたね...
(docについては、ユーザーにunmanaged部分を見せなければ大丈夫なのではと思います)

@yamachu
Copy link
Member

yamachu commented Aug 5, 2023

C-APIのheaderを見てbindgenのdocumentを読んでいたら、ifdefをどうも評価してくれていそうな雰囲気を感じ、clangのargumentsを足す実験をしてみました。

yamachu/VoicevoxEngineSharp@35c6e62
yamachu/VoicevoxEngineSharp@95abeef

そうしたところenumの特別対応なども不要になり、bindgen -> csbindgen -> csのきれいな流れが出来たので報告です。

これをベースに軽く作ってみます

@yamachu
Copy link
Member

yamachu commented Aug 6, 2023

UserDictなどで使用されている固定長の文字列が正常に出力されないのを確認しました…

word_uuid: &[u8; 16],

output_word_uuid: NonNull<[u8; 16]>,

をcsbindgenがサポートしていないのかな…もうちょい調べてみます

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants