質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Q&A

解決済

1回答

264閲覧

RustとObjective-Cの橋渡しのコードにて、Rust側のブロックをもう片方に引数として渡す方法について

tasuren

総合スコア76

Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

0グッド

0クリップ

投稿2023/12/29 14:13

実現したいこと

このGitHubに公開されているコードにて、ConcreteBlockの構造体のインスタンスの参照を外しもう一度参照を付け、msg_send!にて&*blockのようにしてブロックを渡しています。

これは、&TのTがRefEncodeを満たす時にmsg_send!へ値を渡せるようになることから、それを満たすためにやっているのだと思います。
というのも、ConcreteBlockにはDeref<Target = Block<A, R>>が実装されていて、参照外しを行うことでRefEncodeを満たすBlockにすることが可能です。なので、それをした後に&を付け&Tの形にすることで、msg_send!に渡せるようにするという具合です。
しかし、この&を付けても動く理由がわかりません。

発生している問題

なぜ&を付けても動く理由がわからないのかというと、Objective-Cのコードでブロックを作り渡す場合、completionHandler: ^()(...)のように*など書かずにそのままブロックを渡します。ここで、なぜObjective-Cではそのまま渡したのに、Rustの方でやる場合は&を付けても問題なく動くのかが疑問になります。

該当のソースコード

前述したこのコードの引用です。

rust

1 pub fn begin_sheet<F, W>(&self, window: &Window<W>, completion: F) 2 where 3 F: Fn() + Send + Sync + 'static, 4 W: WindowDelegate + 'static 5 { 6 let block = ConcreteBlock::new(move |_response: NSInteger| { 7 completion(); 8 }); 9 let block = block.copy(); 10 11 unsafe { 12 let _: () = msg_send![&*self.objc, beginSheet: &*window.objc, completionHandler: &*block]; 13 } 14 }

試したこと

その&を消してみたりしましたが、前述の&Tを満たさなくなりますので、エラーが出ました。

補足情報(FW/ツールのバージョンなど)

フレームワーク:objc2 クレート, block2 クレート
rustc: 1.74.0 (79e9716c9 2023-11-13)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

https://crates.io/crates/block
このサイトを参考にするなら

objective

1int32_t sum(int32_t (^block)(int32_t, int32_t)) { 2 return block(5, 8); 3}

Rust

1unsafe fn sum(block: &Block<(i32, i32), i32>) -> i32 { 2 block.call((5, 8)) 3}

^blockBlockのポインタだと解釈できますね
^はC++/CLIなどでハンドル演算子や追尾参照型などと呼ばれるポインタの一種ですが、objective-cでも同様ならアドレスを渡すのに&をつけるのは妥当かと考えられます

&*blockで参照先のインスタンスのアドレスを再取得していることになるでしょう

投稿2023/12/30 08:51

TokoToko123

総合スコア26

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tasuren

2023/12/30 09:35

納得がある程度いきました。 回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問