Skip to content

Commit

Permalink
Add support for c_void as an opaque C++ type
Browse files Browse the repository at this point in the history
  • Loading branch information
dpaoliello committed Aug 21, 2023
1 parent eb06f52 commit 85ad77b
Show file tree
Hide file tree
Showing 10 changed files with 27 additions and 6 deletions.
3 changes: 2 additions & 1 deletion gen/src/write.rs
Expand Up @@ -210,7 +210,7 @@ fn pick_includes_and_builtins(out: &mut OutFile, apis: &[Api]) {
Some(Isize) => out.builtin.rust_isize = true,
Some(CxxString) => out.include.string = true,
Some(RustString) => out.builtin.rust_string = true,
Some(Bool | Char | F32 | F64) | None => {}
Some(Bool | Char | F32 | F64 | Cvoid) | None => {}
},
Type::RustBox(_) => out.builtin.rust_box = true,
Type::RustVec(_) => out.builtin.rust_vec = true,
Expand Down Expand Up @@ -1322,6 +1322,7 @@ fn write_atom(out: &mut OutFile, atom: Atom) {
F64 => write!(out, "double"),
CxxString => write!(out, "::std::string"),
RustString => write!(out, "::rust::String"),
Cvoid => write!(out, "void"),
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/extern_type.rs
Expand Up @@ -2,6 +2,7 @@ use self::kind::{Kind, Opaque, Trivial};
use crate::CxxString;
#[cfg(feature = "alloc")]
use alloc::string::String;
use core::ffi::c_void;

/// A type for which the layout is determined by its C++ definition.
///
Expand Down Expand Up @@ -222,4 +223,5 @@ impl_extern_type! {

[Opaque]
CxxString = "std::string"
c_void = "void"
}
3 changes: 3 additions & 0 deletions syntax/atom.rs
Expand Up @@ -20,6 +20,7 @@ pub enum Atom {
F64,
CxxString,
RustString,
Cvoid,
}

impl Atom {
Expand All @@ -46,6 +47,7 @@ impl Atom {
"f64" => Some(F64),
"CxxString" => Some(CxxString),
"String" => Some(RustString),
"c_void" => Some(Cvoid),
_ => None,
}
}
Expand Down Expand Up @@ -77,6 +79,7 @@ impl AsRef<str> for Atom {
F64 => "f64",
CxxString => "CxxString",
RustString => "String",
Cvoid => "c_void",
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions syntax/check.rs
Expand Up @@ -128,7 +128,7 @@ fn check_type_rust_vec(cx: &mut Check, ty: &Ty1) {
Bool | Char | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32
| F64 | RustString,
) => return,
Some(CxxString) => {}
Some(CxxString | Cvoid) => {}
}
}
Type::Str(_) => return,
Expand Down Expand Up @@ -169,7 +169,7 @@ fn check_type_shared_ptr(cx: &mut Check, ptr: &Ty1) {
Bool | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64
| CxxString,
) => return,
Some(Char | RustString) => {}
Some(Char | RustString | Cvoid) => {}
}
} else if let Type::CxxVector(_) = &ptr.inner {
cx.error(ptr, "std::shared_ptr<std::vector> is not supported yet");
Expand All @@ -192,7 +192,7 @@ fn check_type_weak_ptr(cx: &mut Check, ptr: &Ty1) {
Bool | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64
| CxxString,
) => return,
Some(Char | RustString) => {}
Some(Char | RustString | Cvoid) => {}
}
} else if let Type::CxxVector(_) = &ptr.inner {
cx.error(ptr, "std::weak_ptr<std::vector> is not supported yet");
Expand All @@ -218,7 +218,7 @@ fn check_type_cxx_vector(cx: &mut Check, ptr: &Ty1) {
U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64 | CxxString,
) => return,
Some(Char) => { /* todo */ }
Some(Bool | RustString) => {}
Some(Bool | RustString | Cvoid) => {}
}
}

Expand Down
2 changes: 1 addition & 1 deletion syntax/pod.rs
Expand Up @@ -10,7 +10,7 @@ impl<'a> Types<'a> {
match atom {
Bool | Char | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64
| Isize | F32 | F64 => true,
CxxString | RustString => false,
CxxString | RustString | Cvoid => false,
}
} else if let Some(strct) = self.structs.get(ident) {
derive::contains(&strct.derives, Trait::Copy)
Expand Down
3 changes: 3 additions & 0 deletions syntax/tokens.rs
Expand Up @@ -20,6 +20,9 @@ impl ToTokens for Type {
} else if ident.rust == RustString {
let span = ident.rust.span();
tokens.extend(quote_spanned!(span=> ::cxx::alloc::string::));
} else if ident.rust == Cvoid {
let span = ident.rust.span();
tokens.extend(quote_spanned!(span=> ::core::ffi::));
}
ident.to_tokens(tokens);
}
Expand Down
2 changes: 2 additions & 0 deletions tests/ffi/lib.rs
Expand Up @@ -207,6 +207,8 @@ pub mod ffi {

fn c_get_use_count(weak: &WeakPtr<C>) -> usize;

unsafe fn c_takes_void_star(value: *const c_void);

#[rust_name = "i32_overloaded_method"]
fn cOverloadedMethod(&self, x: i32) -> String;
#[rust_name = "str_overloaded_method"]
Expand Down
6 changes: 6 additions & 0 deletions tests/ffi/tests.cc
Expand Up @@ -598,6 +598,12 @@ size_t c_get_use_count(const std::weak_ptr<C> &weak) noexcept {
return weak.use_count();
}

void c_takes_void_star(const void *value) noexcept {
if (value == nullptr) {
cxx_test_suite_set_correct();
}
}

extern "C" C *cxx_test_suite_get_unique_ptr() noexcept {
return std::unique_ptr<C>(new C{2020}).release();
}
Expand Down
2 changes: 2 additions & 0 deletions tests/ffi/tests.h
Expand Up @@ -190,6 +190,8 @@ const rust::Vec<uint8_t> &c_try_return_ref_rust_vec(const C &c);

size_t c_get_use_count(const std::weak_ptr<C> &weak) noexcept;

void c_takes_void_star(const void *value) noexcept;

void c_take_trivial_ptr(std::unique_ptr<D> d);
void c_take_trivial_ref(const D &d);
void c_take_trivial_mut_ref(D &d);
Expand Down
2 changes: 2 additions & 0 deletions tests/test.rs
Expand Up @@ -362,6 +362,8 @@ fn test_extern_opaque() {
let f = ffi2::c_return_ns_opaque_ptr();
check!(ffi2::c_take_opaque_ns_ref(f.as_ref().unwrap()));
check!(ffi2::c_take_opaque_ns_ptr(f));

check!(unsafe { ffi::c_takes_void_star(core::ptr::null()) });
}

#[test]
Expand Down

0 comments on commit 85ad77b

Please sign in to comment.