1

I understand that I can give a function a static linker symbol name like this:

// The linker symbol produced for this function will be named
// "foo_bar", not "asdf" or some mangled version of "asdf".
#[unsafe(export_name = "foo_bar")]
extern "C" fn asdf() {
    // ...
}

Is there a way to provide a dynamically generated symbol name? For example:

trait MyTrait {
    const NAME: &'static str;
    // ...
}

struct MyStruct<T: MyTrait> {
    data: T
}

impl<T: MyTrait> MyStruct<T> {
    #[unsafe(export_name = "my_prefix_new_" + T::NAME)]
    extern "C" c_new() -> *mut MyStruct<T> {
        // ...
    }
}

I want to do this to make it easier to write Rust plugins (cdylib) for an existing C-based plugin system.

Perhaps there's a way to collect the desired names when building and use them to construct a linker script that Cargo passes to the linker?

5
  • According to ABI docs, export_name is a MetaNameValueStr. So there's no hope of doing something like export_name = "my_prefix_new_" + T::NAME, which makes it non-trivial (read: proc-macro fun). Commented Sep 19 at 7:11
  • With proc macro though it's certainly possible to achieve what you want. Probably a derive macro with a helper attribute where you can pass in arbitrary input like the symbol name and an implementation function path. There's a lot to learn if you haven't written one before, but I wouldn't call it difficult. So it's just a matter of evaluating whether the DRY benefit is worth this extra code with the associated complexity. Commented Sep 19 at 7:22
  • @cyqsimon I thought of proc macros too, but I'm not sure it would work here. The problem is: the proc macro can't access T::NAME which is a const &'static str and potentially lives in a completely different part of the code. Commented Sep 19 at 10:00
  • @Jmb It wouldn't work using T::NAME I concur. But I assumed that he probably has some flexibility on how exactly to implement this. From the limited info I've got, I don't see why he can't just use the name of the struct (which IS available to the derive macro), potentially with an optional attribute argument to override the generated name. Although of course without knowing OP's exact objectives and constraints I can only give tentative suggestions. Commented Sep 19 at 11:41
  • Macros are accepted: play.rust-lang.org/…. There is no way you can use a type-dependent name. Commented Sep 20 at 19:52

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.