Skip to content

Commit

Permalink
Support #[export_name = "..."]
Browse files Browse the repository at this point in the history
  • Loading branch information
hadashiA committed Jan 5, 2024
1 parent 2c57dce commit ae875ca
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 8 deletions.
10 changes: 8 additions & 2 deletions csbindgen/src/emitter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::alias_map::AliasMap;
use crate::builder::BindgenOptions;
use crate::type_meta::*;
use crate::type_meta::ExportSymbolNaming::{ExportName, NoMangle};
use crate::util::*;

pub fn emit_rust_method(list: &Vec<ExternMethod>, options: &BindgenOptions) -> String {
Expand Down Expand Up @@ -152,9 +153,14 @@ pub fn emit_csharp(
}
}

let entry_point = match &item.export_naming {
NoMangle => &item.method_name,
ExportName(export_name) => export_name
};

let entry_point = match options.csharp_entry_point_prefix.as_str() {
"" => format!("{method_prefix}{method_name}"),
x => format!("{x}{method_name}"),
"" => format!("{method_prefix}{entry_point}"),
x => format!("{x}{entry_point}"),
};
let return_type = match &item.return_type {
Some(x) => {
Expand Down
43 changes: 37 additions & 6 deletions csbindgen/src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::{alias_map::AliasMap, builder::BindgenOptions, field_map::FieldMap, type_meta::*};
use regex::Regex;
use std::collections::HashSet;
use syn::{ForeignItem, Item, Pat, ReturnType};
use syn::{ForeignItem, Ident, Item, Meta, MetaNameValue, Pat, ReturnType};
use crate::type_meta::ExportSymbolNaming::{ExportName, NoMangle};

enum FnItem {
ForeignItem(syn::ForeignItemFn),
Expand Down Expand Up @@ -56,8 +57,8 @@ pub fn collect_extern_method(
) {
for item in depth_first_module_walk(&ast.items) {
if let Item::Fn(m) = item {
if m.sig.abi.is_some() {
// has extern
// has extern "C"
if m.sig.abi.as_ref().and_then(|x| x.name.as_ref()).filter(|x| x.value() == "C").is_some() {
let method = parse_method(FnItem::Item(m.clone()), options);
if let Some(x) = method {
list.push(x);
Expand All @@ -68,9 +69,9 @@ pub fn collect_extern_method(
}

fn parse_method(item: FnItem, options: &BindgenOptions) -> Option<ExternMethod> {
let (sig, attrs) = match item {
FnItem::ForeignItem(x) => (x.sig, x.attrs),
FnItem::Item(x) => (x.sig, x.attrs),
let (sig, attrs, is_foreign_item) = match item {
FnItem::ForeignItem(x) => (x.sig, x.attrs, true),
FnItem::Item(x) => (x.sig, x.attrs, false),
};

let method_name = sig.ident.to_string();
Expand Down Expand Up @@ -114,6 +115,35 @@ fn parse_method(item: FnItem, options: &BindgenOptions) -> Option<ExternMethod>
return_type = Some(rust_type);
}

// check attrs
let mut export_naming = NoMangle;
if (!is_foreign_item) {
let found = attrs.iter()
.map(|attr| {
let name = &attr.path.segments.last().unwrap().ident;
if (name == "no_mangle") {
return Some(NoMangle)
} else if (name == "export_name") {
if let Ok(Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(x), .. })) = attr.parse_meta() {
return Some(ExportName(x.value()));
}
}
None
})
.flatten()
.next();

if let Some(x) = found {
export_naming = x;
} else {
println!(
"csbindgen can't handle this function because there is neither #[no_mangle] nor #[export_name] so ignore generate, method_name: {}",
method_name
);
return None;
}
}

// doc
let doc_comment = attrs
.iter()
Expand All @@ -124,6 +154,7 @@ fn parse_method(item: FnItem, options: &BindgenOptions) -> Option<ExternMethod>
if !method_name.is_empty() && (options.method_filter)(method_name.clone()) {
return Some(ExternMethod {
method_name,
export_naming,
parameters,
return_type,
doc_comment,
Expand Down
7 changes: 7 additions & 0 deletions csbindgen/src/type_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,19 @@ pub struct FieldMember {
pub rust_type: RustType,
}

#[derive(Clone, Debug)]
pub enum ExportSymbolNaming {
NoMangle,
ExportName(String),
}

#[derive(Clone, Debug)]
pub struct ExternMethod {
pub method_name: String,
pub doc_comment: Vec<String>,
pub parameters: Vec<Parameter>,
pub return_type: Option<RustType>,
pub export_naming: ExportSymbolNaming,
}

impl ExternMethod {
Expand Down

0 comments on commit ae875ca

Please sign in to comment.