vtable: Don't automatically add extern C
Some checks are pending
autofix.ci / format_fix (push) Waiting to run
autofix.ci / lint_typecheck (push) Waiting to run
CI / build_and_test (--exclude bevy-example, ubuntu-22.04, 1.82) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, stable) (push) Blocked by required conditions
CI / node_test (ubuntu-22.04) (push) Blocked by required conditions
CI / files-changed (push) Waiting to run
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, --exclude bevy-example, windows-2022, 1.82) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, macos-14, stable) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, beta) (push) Blocked by required conditions
CI / build_and_test (ubuntu-22.04, nightly) (push) Blocked by required conditions
CI / node_test (macos-14) (push) Blocked by required conditions
CI / node_test (windows-2022) (push) Blocked by required conditions
CI / python_test (macos-14) (push) Blocked by required conditions
CI / python_test (ubuntu-22.04) (push) Blocked by required conditions
CI / python_test (windows-2022) (push) Blocked by required conditions
CI / cpp_test_driver (macos-13) (push) Blocked by required conditions
CI / cpp_test_driver (ubuntu-22.04) (push) Blocked by required conditions
CI / cpp_test_driver (windows-2022) (push) Blocked by required conditions
CI / cpp_cmake (macos-14, 1.82) (push) Blocked by required conditions
CI / cpp_cmake (ubuntu-22.04, stable) (push) Blocked by required conditions
CI / cpp_cmake (windows-2022, nightly) (push) Blocked by required conditions
CI / cpp_package_test (push) Blocked by required conditions
CI / vsce_build_test (push) Blocked by required conditions
CI / mcu (pico-st7789, thumbv6m-none-eabi) (push) Blocked by required conditions
CI / mcu (pico2-st7789, thumbv8m.main-none-eabihf) (push) Blocked by required conditions
CI / mcu (stm32h735g, thumbv7em-none-eabihf) (push) Blocked by required conditions
CI / mcu-embassy (push) Blocked by required conditions
CI / ffi_32bit_build (push) Blocked by required conditions
CI / docs (push) Blocked by required conditions
CI / wasm (push) Blocked by required conditions
CI / wasm_demo (push) Blocked by required conditions
CI / tree-sitter (push) Blocked by required conditions
CI / updater_test (0.3.0) (push) Blocked by required conditions
CI / fmt_test (push) Blocked by required conditions
CI / esp-idf-quick (push) Blocked by required conditions
CI / android (push) Blocked by required conditions
CI / miri (push) Blocked by required conditions
CI / test-figma-inspector (push) Blocked by required conditions

This commit is contained in:
Olivier Goffart 2025-06-06 11:57:40 +02:00
parent f91b61c8ee
commit af573e6401
10 changed files with 19 additions and 32 deletions

View file

@ -131,7 +131,7 @@ slint-cpp = { version = "=1.12.0", path = "api/cpp", default-features = false }
slint-interpreter = { version = "=1.12.0", path = "internal/interpreter", default-features = false }
slint-macros = { version = "=1.12.0", path = "api/rs/macros", default-features = false }
vtable = { version = "0.2.1", path = "helper_crates/vtable", default-features = false }
vtable = { version = "0.3", path = "helper_crates/vtable" }
by_address = { version = "1.0.4" }
bytemuck = { version = "1.13.1" }

View file

@ -3,6 +3,10 @@
# Changelog
All notable changes to this crate will be documented in this file.
## [0.3.0]
- Don't automatically add "extern C" to the function that do not have it.
## [0.2.1] - 2024-12-18
- Fixed Warnings

View file

@ -3,7 +3,7 @@
[package]
name = "vtable"
version = "0.2.1"
version = "0.3.0"
authors = ["Slint Developers <info@slint.dev>"]
edition = "2021"
license = "MIT OR Apache-2.0"
@ -14,7 +14,7 @@ homepage = "https://slint.dev"
[lib]
[dependencies]
vtable-macro = { version = "=0.2.1", path = "./macro" }
vtable-macro = { version = "=0.3.0", path = "./macro" }
const-field-offset = { version = "0.1", path = "../const-field-offset" }
stable_deref_trait = { version = "1.2.0", default-features = false }
portable-atomic = "1"

View file

@ -3,7 +3,7 @@
[package]
name = "vtable-macro"
version = "0.2.1"
version = "0.3.0"
authors = ["Slint Developers <info@slint.dev>"]
edition = "2021"
license = "MIT OR Apache-2.0"

View file

@ -68,7 +68,6 @@ allowing to access methods from the trait directly from VRef.
This macro does the following transformation:
For function type fields:
- If the function has no ABI, it is changed to `extern "C"` (unless `no_extern` is passed as `#[vtable(no_extern)]`)
- `unsafe` is added to the signature, since it is unsafe to call these functions directly from
the vtable without having a valid pointer to the actual object. But if the original function was
marked unsafe, the unsafety is forwarded to the trait.
@ -112,7 +111,7 @@ use vtable::*;
#[repr(C)]
struct AnimalVTable {
/// Pointer to a function that make noise.
/// `unsafe` and `extern "C"` will automatically be added
/// `unsafe` will automatically be added
make_noise: fn(VRef<AnimalVTable>, i32) -> i32,
/// if there is a 'drop' member, it is considered as the destructor
@ -165,9 +164,7 @@ assert_eq!(dog.is_hungry, true);
*/
#[proc_macro_attribute]
pub fn vtable(attr: TokenStream, item: TokenStream) -> TokenStream {
let no_extern = attr.to_string().trim() == "no_extern";
pub fn vtable(_attr: TokenStream, item: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(item as ItemStruct);
let fields = if let Fields::Named(fields) = &mut input.fields {
@ -386,19 +383,6 @@ pub fn vtable(attr: TokenStream, item: TokenStream) -> TokenStream {
// Add unsafe: The function are not safe to call unless the self parameter is of the correct type
f.unsafety = Some(Default::default());
// Add extern "C" if it isn't there
if let Some(a) = &f.abi {
if !a
.name
.as_ref()
.map(|s| matches!(s.value().as_str(), "C" | "C-unwind"))
.unwrap_or(false)
{
return Error::new(a.span(), "invalid ABI").to_compile_error().into();
}
} else if !no_extern {
f.abi = Some(parse_str("extern \"C\"").unwrap());
}
sig_extern.abi.clone_from(&f.abi);
let mut wrap_trait_call = None;

View file

@ -24,9 +24,6 @@ use vtable::*;
struct AnimalVTable {
/// pointer to a function that makes a noise. The `VRef<AnimalVTable>` is the type of
/// the self object.
///
/// Note: the #[vtable] macro will automatically add `extern "C"` if that is missing.
/// (unless `no_extern` is specified)
make_noise: fn(VRef<AnimalVTable>, i32) -> i32,
/// if there is a 'drop' member, it is considered as the destructor.

View file

@ -21,7 +21,7 @@ mod svg;
#[allow(missing_docs)]
#[cfg_attr(not(feature = "ffi"), i_slint_core_macros::remove_extern)]
#[vtable::vtable(no_extern)]
#[vtable::vtable]
#[repr(C)]
pub struct OpaqueImageVTable {
drop_in_place: extern "C-unwind" fn(VRefMut<OpaqueImageVTable>) -> Layout,

View file

@ -42,7 +42,7 @@ impl From<IndexRange> for core::ops::Range<usize> {
/// A ItemTree is representing an unit that is allocated together
#[cfg_attr(not(feature = "ffi"), i_slint_core_macros::remove_extern)]
#[vtable(no_extern)]
#[vtable]
#[repr(C)]
pub struct ItemTreeVTable {
/// Visit the children of the item at index `index`.
@ -1049,7 +1049,7 @@ impl<'a> From<&'a [ItemTreeNode]> for ItemTreeNodeArray<'a> {
}
#[cfg_attr(not(feature = "ffi"), i_slint_core_macros::remove_extern)]
#[vtable(no_extern)]
#[vtable]
#[repr(C)]
/// Object to be passed in visit_item_children method of the ItemTree.
pub struct ItemVisitorVTable {

View file

@ -113,7 +113,7 @@ pub enum RenderingResult {
/// Items are the nodes in the render tree.
#[cfg_attr(not(feature = "ffi"), i_slint_core_macros::remove_extern)]
#[vtable(no_extern)]
#[vtable]
#[repr(C)]
pub struct ItemVTable {
/// This function is called by the run-time after the memory for the item

View file

@ -22,15 +22,17 @@ use i_slint_core_macros::SlintElement;
use vtable::{VRef, VRefMut};
/// Interface for native menu and menubar
#[cfg_attr(not(feature = "ffi"), i_slint_core_macros::remove_extern)]
#[vtable::vtable]
#[repr(C)]
pub struct MenuVTable {
/// destructor
drop: fn(VRefMut<MenuVTable>),
drop: extern "C-unwind" fn(VRefMut<MenuVTable>),
/// Return the list of items for the sub menu (or the main menu of parent is None)
sub_menu: fn(VRef<MenuVTable>, Option<&MenuEntry>, &mut SharedVector<MenuEntry>),
sub_menu:
extern "C-unwind" fn(VRef<MenuVTable>, Option<&MenuEntry>, &mut SharedVector<MenuEntry>),
/// Handler when the menu entry is activated
activate: fn(VRef<MenuVTable>, &MenuEntry),
activate: extern "C-unwind" fn(VRef<MenuVTable>, &MenuEntry),
}
struct ShadowTreeNode {