I'm trying to implement a Rust procedural macro that exports a C-compatible function for a driver I'm writing. Here's my macro:
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{ItemStruct, parse_macro_input};
#[proc_macro_attribute]
pub fn export_driver(_attr: TokenStream, item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as ItemStruct);
let name = &input.ident;
let expanded = quote! {
#input
#[no_mangle]
pub unsafe extern "C" fn init() -> i32 {
#name::init()
}
};
TokenStream::from(expanded)
}
I try to use the macro like this:
#[export_driver]
struct MyDriver;
But I get the error:
[export_driver]
| ^^^^^^^^^^^^^^^^ usage of unsafe attribute
|
= note: this error originates in the attribute macro `export_driver` (in Nightly builds, run with -Z macro-backtrace for more info)
help: wrap the attribute in `unsafe(...)`
|
4 | unsafe(#[export_driver])
| +++++++
If I try what the compiler suggests, I get another error:
error: expected item, found keyword `unsafe`
--> my-driver\src\main.rs:4:1
|
4 | unsafe(#[export_driver])
| ^^^^^^ expected item
Removing #[no_mangle] suppresses the first error in the original code, but I need to keep the exported function name.
Question: How can I keep #[no_mangle] in the generated function while still applying my macro to a struct?
#[unsafe(no_mangle)]. You can report a bug for the broken suggestion.