Last active
November 9, 2022 13:14
-
-
Save dacci/65a684128ce109c572b2eedc65d3847e to your computer and use it in GitHub Desktop.
Calling Objective-C function that takes block as an argument from Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| fn main() { | |
| println!("cargo:rustc-link-search={}/Library/Developer/Xcode/DerivedData/interop-cohciqqveewsnccwrnprodrghxtq/Build/Products/Debug", env!("HOME")); | |
| println!("cargo:rustc-link-lib=interop"); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #import <Foundation/Foundation.h> | |
| typedef void (^CompletionHandler)(int); | |
| @interface DeepThought : NSObject | |
| + (void)calculateWithCompletionHandler:(CompletionHandler)completionHandler; | |
| @end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #import "DeepThought.h" | |
| #include <stdio.h> | |
| @implementation DeepThought | |
| + (void)calculateWithCompletionHandler:(CompletionHandler)completionHandler { | |
| printf("objc: DeepThought::calculateWithCompletionHandler\n"); | |
| if (completionHandler != NULL) { | |
| completionHandler(42); | |
| } | |
| } | |
| @end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| objc: DeepThought::calculateWithCompletionHandler | |
| Rust: answer = 42 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use objc::runtime::Class; | |
| use objc::{class, msg_send, sel, sel_impl}; | |
| use std::ffi::c_int; | |
| use std::mem::size_of; | |
| #[repr(C)] | |
| struct BlockDescriptor { | |
| reserved: usize, | |
| size: usize, | |
| } | |
| #[repr(C)] | |
| struct BlockLiteral { | |
| isa: *const Class, | |
| flags: c_int, | |
| reserved: c_int, | |
| invoke: extern "C" fn(&Self, c_int), | |
| descriptor: Box<BlockDescriptor>, | |
| } | |
| extern "C" fn handler(_: &BlockLiteral, answer: c_int) { | |
| println!("Rust: answer = {answer}") | |
| } | |
| fn main() { | |
| let literal = BlockLiteral { | |
| isa: class!(NSObject), | |
| flags: 0, | |
| reserved: 0, | |
| invoke: handler, | |
| descriptor: Box::new(BlockDescriptor { | |
| reserved: 0, | |
| size: size_of::<BlockLiteral>(), | |
| }), | |
| }; | |
| let _: () = unsafe { | |
| msg_send![ | |
| class!(DeepThought), | |
| calculateWithCompletionHandler: &literal | |
| ] | |
| }; | |
| } |
Author
dacci
commented
Nov 9, 2022
- Language Specification for Blocks
- Block Implementation Specification
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment