C++: Fix ABI mismatch with Slice on MSVC AArch64
Some checks are pending
autofix.ci / format_fix (push) Waiting to run
autofix.ci / lint_typecheck (push) Waiting to run
CI / python_test (windows-2022) (push) Blocked by required conditions
CI / files-changed (push) Waiting to run
CI / build_and_test (--exclude bevy-example, ubuntu-22.04, 1.85) (push) Blocked by required conditions
CI / mcu (pico-st7789, thumbv6m-none-eabi) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, --exclude bevy-example, windows-2022, 1.85) (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 (--exclude ffmpeg --exclude gstreamer-player, windows-2022, stable) (push) Blocked by required conditions
CI / build_and_test (ubuntu-22.04, nightly-2025-08-15) (push) Blocked by required conditions
CI / node_test (macos-14) (push) Blocked by required conditions
CI / node_test (ubuntu-22.04) (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 / 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.85) (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 / 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 / android (push) Blocked by required conditions
CI / miri (push) Blocked by required conditions
CI / cpp_package_test (push) Blocked by required conditions
CI / vsce_build_test (push) Blocked by required conditions
CI / fmt_test (push) Blocked by required conditions
CI / esp-idf-quick (push) Blocked by required conditions
CI / test-figma-inspector (push) Blocked by required conditions

The second constructor of `Slice` causes the Slice to be passed
differently (in different register) as a return value.

So remove that constructor and use a helper function to
construct a Slice
This commit is contained in:
Olivier Goffart 2025-08-19 14:11:41 +02:00
parent fd28676ab6
commit a0192d443e
8 changed files with 65 additions and 86 deletions

View file

@ -500,10 +500,7 @@ inline Struct::Struct(std::initializer_list<std::pair<std::string_view, Value>>
inline std::optional<Value> Struct::get_field(std::string_view name) const
{
using namespace cbindgen_private;
cbindgen_private::Slice<uint8_t> name_view {
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(name.data())),
name.size()
};
cbindgen_private::Slice<uint8_t> name_view = slint::private_api::string_to_slice(name);
if (cbindgen_private::Value *field_val =
cbindgen_private::slint_interpreter_struct_get_field(&inner, name_view)) {
return Value(std::move(field_val));
@ -513,10 +510,7 @@ inline std::optional<Value> Struct::get_field(std::string_view name) const
}
inline void Struct::set_field(std::string_view name, const Value &value)
{
cbindgen_private::Slice<uint8_t> name_view {
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(name.data())),
name.size()
};
cbindgen_private::Slice<uint8_t> name_view = slint::private_api::string_to_slice(name);
cbindgen_private::slint_interpreter_struct_set_field(&inner, name_view, value.inner);
}
@ -661,11 +655,8 @@ public:
std::optional<Value> invoke(std::string_view name, std::span<const Value> args) const
{
using namespace cbindgen_private;
Slice<Box<cbindgen_private::Value>> args_view {
const_cast<Box<cbindgen_private::Value> *>(
reinterpret_cast<const Box<cbindgen_private::Value> *>(args.data())),
args.size()
};
Slice<Box<cbindgen_private::Value>> args_view = slint::private_api::make_slice(
reinterpret_cast<const Box<cbindgen_private::Value> *>(args.data()), args.size());
if (cbindgen_private::Value *rval_inner = slint_interpreter_component_instance_invoke(
inner(), slint::private_api::string_to_slice(name), args_view)) {
return Value(std::move(rval_inner));
@ -796,12 +787,11 @@ public:
std::span<const Value> args) const
{
using namespace cbindgen_private;
Slice<cbindgen_private::Box<cbindgen_private::Value>> args_view {
const_cast<cbindgen_private::Box<cbindgen_private::Value> *>(
reinterpret_cast<const cbindgen_private::Box<cbindgen_private::Value> *>(
args.data())),
args.size()
};
Slice<cbindgen_private::Box<cbindgen_private::Value>> args_view =
slint::private_api::make_slice(
reinterpret_cast<const cbindgen_private::Box<cbindgen_private::Value> *>(
args.data()),
args.size());
if (cbindgen_private::Value *rval_inner =
slint_interpreter_component_instance_invoke_global(
inner(), slint::private_api::string_to_slice(global),

View file

@ -95,10 +95,7 @@ public:
static SharedVector<ElementHandle> find_by_accessible_label(const ComponentHandle<T> &component,
std::string_view label)
{
cbindgen_private::Slice<uint8_t> label_view {
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(label.data())),
label.size()
};
cbindgen_private::Slice<uint8_t> label_view = private_api::string_to_slice(label);
auto vrc = component.into_dyn();
SharedVector<ElementHandle> result;
cbindgen_private::slint_testing_element_find_by_accessible_label(
@ -112,10 +109,7 @@ public:
static SharedVector<ElementHandle> find_by_element_id(const ComponentHandle<T> &component,
std::string_view element_id)
{
cbindgen_private::Slice<uint8_t> element_id_view {
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(element_id.data())),
element_id.size()
};
cbindgen_private::Slice<uint8_t> element_id_view = private_api::string_to_slice(element_id);
auto vrc = component.into_dyn();
SharedVector<ElementHandle> result;
cbindgen_private::slint_testing_element_find_by_element_id(
@ -129,10 +123,8 @@ public:
static SharedVector<ElementHandle>
find_by_element_type_name(const ComponentHandle<T> &component, std::string_view type_name)
{
cbindgen_private::Slice<uint8_t> element_type_name_view {
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(type_name.data())),
type_name.size()
};
cbindgen_private::Slice<uint8_t> element_type_name_view =
private_api::string_to_slice(type_name);
auto vrc = component.into_dyn();
SharedVector<ElementHandle> result;
cbindgen_private::slint_testing_element_find_by_element_type_name(

View file

@ -117,8 +117,8 @@ inline SharedVector<float> solve_box_layout(const cbindgen_private::BoxLayoutDat
cbindgen_private::Slice<int> repeater_indexes)
{
SharedVector<float> result;
cbindgen_private::Slice<uint32_t> ri { reinterpret_cast<uint32_t *>(repeater_indexes.ptr),
repeater_indexes.len };
cbindgen_private::Slice<uint32_t> ri =
make_slice(reinterpret_cast<uint32_t *>(repeater_indexes.ptr), repeater_indexes.len);
cbindgen_private::slint_solve_box_layout(&data, ri, &result);
return result;
}
@ -233,9 +233,7 @@ inline SharedString translate_from_bundle(std::span<const char8_t *const> strs,
{
SharedString result;
cbindgen_private::slint_translate_from_bundle(
cbindgen_private::Slice<const char *>(
const_cast<char const **>(reinterpret_cast<char const *const *>(strs.data())),
strs.size()),
make_slice((reinterpret_cast<char const *const *>(strs.data())), strs.size()),
arguments, &result);
return result;
}
@ -246,16 +244,13 @@ translate_from_bundle_with_plural(std::span<const char8_t *const> strs,
cbindgen_private::Slice<SharedString> arguments, int n)
{
SharedString result;
cbindgen_private::Slice<const char *> strs_slice(
const_cast<char const **>(reinterpret_cast<char const *const *>(strs.data())),
strs.size());
cbindgen_private::Slice<uint32_t> indices_slice(
const_cast<uint32_t *>(reinterpret_cast<const uint32_t *>(indices.data())),
indices.size());
cbindgen_private::Slice<uintptr_t (*)(int32_t)> plural_rules_slice(
const_cast<uintptr_t (**)(int32_t)>(
reinterpret_cast<uintptr_t (*const *)(int32_t)>(plural_rules.data())),
plural_rules.size());
cbindgen_private::Slice<const char *> strs_slice =
make_slice(reinterpret_cast<char const *const *>(strs.data()), strs.size());
cbindgen_private::Slice<uint32_t> indices_slice =
make_slice(reinterpret_cast<const uint32_t *>(indices.data()), indices.size());
cbindgen_private::Slice<uintptr_t (*)(int32_t)> plural_rules_slice =
make_slice(reinterpret_cast<uintptr_t (*const *)(int32_t)>(plural_rules.data()),
plural_rules.size());
cbindgen_private::slint_translate_from_bundle_with_plural(
strs_slice, indices_slice, plural_rules_slice, arguments, n, &result);
return result;

View file

@ -284,12 +284,7 @@ inline Image load_image_from_embedded_data(std::span<const uint8_t> data,
{
cbindgen_private::types::Image img(cbindgen_private::types::Image::ImageInner_None());
cbindgen_private::types::slint_image_load_from_embedded_data(
slint::cbindgen_private::Slice<uint8_t> { const_cast<uint8_t *>(data.data()),
data.size() },
slint::cbindgen_private::Slice<uint8_t> {
const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(extension.data())),
extension.size() },
&img);
make_slice(data.data(), data.size()), string_to_slice(extension), &img);
return Image(img);
}

View file

@ -3,6 +3,7 @@
#pragma once
#include <string_view>
#include <span>
#include "slint_string_internal.h"
namespace slint {
@ -223,11 +224,26 @@ private:
};
namespace private_api {
template<typename T>
inline cbindgen_private::Slice<T> make_slice(const T *ptr, size_t len)
{
return cbindgen_private::Slice<T> {
// Rust uses a NonNull, so even empty slices shouldn't use nullptr
.ptr = ptr ? const_cast<T *>(ptr) : reinterpret_cast<T *>(sizeof(T)),
.len = len,
};
}
template<typename T, size_t Extent>
inline cbindgen_private::Slice<std::remove_const_t<T>> make_slice(std::span<T, Extent> span)
{
return make_slice(span.data(), span.size());
}
inline cbindgen_private::Slice<uint8_t> string_to_slice(std::string_view str)
{
return cbindgen_private::Slice<uint8_t> {
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(str.data())), str.size()
};
return make_slice(reinterpret_cast<const uint8_t *>(str.data()), str.size());
}
}

View file

@ -216,8 +216,7 @@ public:
inline std::optional<SharedString> register_font_from_data(const uint8_t *data, std::size_t len)
{
SharedString maybe_err;
cbindgen_private::slint_register_font_from_data(
&inner, { const_cast<uint8_t *>(data), len }, &maybe_err);
cbindgen_private::slint_register_font_from_data(&inner, make_slice(data, len), &maybe_err);
if (!maybe_err.empty()) {
return maybe_err;
} else {