Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Static class name causes an error when loading into the same process from different dylibs #29

Open
ilmai opened this issue Feb 13, 2025 · 7 comments
Labels
bug Something isn't working

Comments

@ilmai
Copy link

ilmai commented Feb 13, 2025

Name of the issue is what I'm imagining is going on anyway.

I'm creating an audio effect plugin for use in DAWs (Digital Audio Workstations). The plugin is being distributed in two formats, CLAP and VST3, which for the purposes of this bug just means that they're separate dylibs. Now, I can add multiple instances of the plugin just fine if they're the same format, but adding two plugins with different formats causes the following error:

panicked at /Users/.../.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/raw-window-metal-1.0.0/src/observer.rs:12:1:
could not create new class RawWindowMetalLayer. Perhaps a class with that name already exists?

If I understand the situation right, one of the dylibs is trying to create a class instance with a name that the other dylib has already used. Presumably the same error would happen if there was another plugin using this crate.

The way I'm solving this in my own code is that I'm adding a random prefix to any ObjC class names I'm declaring to avoid this exact error.

@madsmtm madsmtm added the bug Something isn't working label Feb 13, 2025
@madsmtm
Copy link
Member

madsmtm commented Feb 13, 2025

Hmm, how would you go about solving this if the classes were defined in pure Objective-C? Is the assumption then just that the dynamic linker says "they have the same name, so they're probably the same", and only creates one class? That seems like a place ripe for unsoundness.

@madsmtm
Copy link
Member

madsmtm commented Feb 13, 2025

(I'm considering how to resolve this more generally in objc2 too).

@madsmtm
Copy link
Member

madsmtm commented Feb 13, 2025

I suspect a fix for you would be to create a shared dylib that re-exports raw-window-metal for the others to use (that way you avoid duplication of the internal static that tracks whether the class has been defined or not), but I recognize that may not be as easy as it sounds.

@ilmai
Copy link
Author

ilmai commented Feb 13, 2025

No idea about pure ObjC honestly, I'm just using the bare minimum necessary for MacOS compatibility. This is what I'm doing with a custom class in my own code:

        let class_name = format!("plugin-canvas-OsWindowView-{}", Uuid::new_v4().simple().to_string());

        let mut builder = ClassBuilder::new(&class_name, NSView::class())
            .expect(&format!("Class failed to register: {class_name}"));

@madsmtm
Copy link
Member

madsmtm commented Feb 13, 2025

Fair enough.

I'm pretty sure there's not much that raw-window-metal is doing wrong here, I'm gonna consider this mostly an objc2 issue, opened madsmtm/objc2#713 to track it there. Until that is resolved, I'd recommend the route noted in #29 (comment).

@ilmai
Copy link
Author

ilmai commented Feb 14, 2025

Thanks for the comments.

The issue you created is a good ergonomics improvement but wouldn't solve this issue. The issue here is that two dylibs, let's call them A and B, are trying to create a class with the exact same name and the latter of those fails. Any static name doesn't solve the issue. Again, I have no idea how pure ObjC would solve this.

Also, your suggested solution wouldn't work either as that depends on the whole Rust audio plugin ecosystem (which frankly is tiny at this point so "fortunately" that makes the issue less severe) adapting the dylib, which isn't realistic. Also, I'm not using raw-window-metal directly but through slint.

@madsmtm
Copy link
Member

madsmtm commented Feb 14, 2025

The issue you created is a good ergonomics improvement but wouldn't solve this issue. The issue here is that two dylibs, let's call them A and B, are trying to create a class with the exact same name and the latter of those fails. Any static name doesn't solve the issue.

We can choose to just use the class if the names are the same. But I don't want to do that unless I'm certain they're actually the same (which we are not if potentially two versions of raw-window-metal are involved).

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
bug Something isn't working
Development

No branches or pull requests

2 participants