Skip to content

declare_class generates unusable classes #604

Open
@Yuri6037

Description

@Yuri6037

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:

declare_class! {
    pub struct BPXContainer;

    // SAFETY:
    // - The superclass NSObject does not have any subclassing requirements.
    // - Interior mutability is a safe default.
    // - `BPXContainer` does not implement `Drop`.
    unsafe impl ClassType for BPXContainer {
        type Super = NSObject;
        type Mutability = mutability::Mutable;
        const NAME: &'static str = "BPXContainer";
    }

    impl DeclaredClass for BPXContainer {
        type Ivars = ();
    }

    unsafe impl BPXContainer {
        #[method_id(create:)]
        fn create(ty: u8) -> Id<BPXContainer> {
            let obj = Self::alloc().set_ivars(());
            unsafe { msg_send_id![super(obj), init] }
        }
    }
}

The above code is built as a cdylib.
With the following Objective-C code:

#import <Foundation/Foundation.h>

@interface BPXContainer
+(BPXContainer*)create:(uint8_t)ty;
@end

int main() {
    @autoreleasepool {
        BPXContainer *container = [BPXContainer create:'P'];
    }
}

The command line I used to build the Objective-C code is the following:

clang test.m -framework Foundation -L target/debug -lbpxbridge

I expected the code to compile, link and run creating a BPXContainer object which currently is of no use, but instead this happened:

Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_BPXContainer", referenced from:
       in test-a4125c.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

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 named register 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-objc2Affects the `objc2`, `objc2-exception-helper` and/or `objc2-encode` cratesbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions