Open Yuri6037 opened 3 weeks ago
Yes, your statement here is entirely correct:
your crate is not actually declaring classes but instead is expecting to dynamically register classes with an existing runtime
That said, the runtime that it is registered with is the Objective-C runtime itself, so you can use this class from Objective-C. All of this is somewhat documented in declare_class!
, the following line:
The class is guaranteed to have been created and registered with the Objective-C runtime after the
ClassType::class
function has been called.
So what you need to do is call <BPXContainer as ClassType>::class()
sometime before using the class from Objective-C.
This can be accomplished with either a helper function:
// rust
[no_mangle]
extern "C" fn rust_init() {
let _ = BPXContainer::class();
}
// C
void rust_init(void);
int main() {
rust_init();
// Rest of main
}
Or something like the ctor
crate:
#[ctor::ctor]
fn init_bpxcontainer() {
let _ = BPXContainer::class();
}
If so is there any plan [...] to support actual class declaration instead of just dynamic registration?
I have tried to design the macro such that this would be possible in the future. The reason it's not implemented yet is that it is quite hacky in current Rust, we need to emit statics in very special manner that isn't really compatible with rustc
's splitting of files into multiple codegen units, and I wanted to make sure that the crate is built on something robust instead.
There exists a project called objrs
that has done some of this, I want to add experimental support for the same in objc2
, but it's a low priority.
Yes, your statement here is entirely correct:
your crate is not actually declaring classes but instead is expecting to dynamically register classes with an existing runtime
That said, the runtime that it is registered with is the Objective-C runtime itself, so you can use this class from Objective-C. All of this is somewhat documented in
declare_class!
, the following line:The class is guaranteed to have been created and registered with the Objective-C runtime after the
ClassType::class
function has been called.So what you need to do is call
<BPXContainer as ClassType>::class()
sometime before using the class from Objective-C.This can be accomplished with either a helper function:
// rust [no_mangle] extern "C" fn rust_init() { let _ = BPXContainer::class(); } // C void rust_init(void); int main() { rust_init(); // Rest of main }
Or something like the
ctor
crate:#[ctor::ctor] fn init_bpxcontainer() { let _ = BPXContainer::class(); }
If so is there any plan [...] to support actual class declaration instead of just dynamic registration?
I have tried to design the macro such that this would be possible in the future. The reason it's not implemented yet is that it is quite hacky in current Rust, we need to emit statics in very special manner that isn't really compatible with
rustc
's splitting of files into multiple codegen units, and I wanted to make sure that the crate is built on something robust instead.There exists a project called
objrs
that has done some of this, I want to add experimental support for the same inobjc2
, but it's a low priority.
I see thanks for the information. Unfortunately registering the classes is not sufficient as Xcode refuses to link against dynamically looked up symbols it requires the selectors and the class itself to be statically generated (with those special symbols). This means your crate is unusable from Xcode directly, you can only use that feature in order to implement protocols and pass derived objects with those protocol implementations to a function needing it in AppKit or some Apple framework...
I'll look into objrs if that works...
Hello,
After spending time at building a hybrid Rust + Objective C framework, I just did an experiment with the
declare_class
macro present in this crate to remove entirely the Objective C part and do everything in Rust. Unfortunately it appears to not generate usable classes.Consider the following Rust code:
The above code is built as a
cdylib
. With the following Objective-C code:The command line I used to build the Objective-C code is the following:
I expected the code to compile, link and run creating a BPXContainer object which currently is of no use, but instead this happened:
Indeed after a quick
nm
command we see no symbols exported. I've seen that after calling the class() function in a C exported function namedregister
the symbols starts to appear obviously no_OBJC_CLASS_$_BPXContainer
symbol is created...I suppose your crate is not actually declaring classes but instead is expecting to dynamically register classes with an existing runtime, is that correct? If so is there any plan or workaround to support actual class declaration instead of just dynamic registration?