diff --git a/templates/qt_quick/rust/src/interface.rs b/templates/qt_quick/rust/src/interface.rs index 9ddf376..da94277 100644 --- a/templates/qt_quick/rust/src/interface.rs +++ b/templates/qt_quick/rust/src/interface.rs @@ -1,110 +1,91 @@ /* generated by rust_qt_binding_generator */ #![allow(unknown_lints)] #![allow(mutex_atomic, needless_pass_by_value)] -use libc::{c_int, c_void, uint8_t, uint16_t}; +use libc::{c_char, c_ushort, c_int, c_void, uint8_t, uint16_t}; use std::slice; +use std::char::decode_utf16; use std::sync::{Arc, Mutex}; use std::ptr::null; use implementation::*; -#[repr(C)] -pub struct QString { - data: *const uint8_t, - len: c_int, -} - -#[repr(C)] -pub struct QStringIn { - data: *const uint16_t, - len: c_int, -} +pub enum QString {} -impl QStringIn { - fn convert(&self) -> String { - let data = unsafe { slice::from_raw_parts(self.data, self.len as usize) }; - String::from_utf16_lossy(data) - } +fn set_string_from_utf16(s: &mut String, str: *const c_ushort, len: c_int) { + let utf16 = unsafe { slice::from_raw_parts(str, len as usize) }; + let characters = decode_utf16(utf16.iter().cloned()) + .into_iter() + .map(|r| r.unwrap()); + s.clear(); + s.extend(characters); } -impl<'a> From<&'a str> for QString { - fn from(string: &'a str) -> QString { - QString { - len: string.len() as c_int, - data: string.as_ptr(), - } - } -} - -impl<'a> From<&'a String> for QString { - fn from(string: &'a String) -> QString { - QString { - len: string.len() as c_int, - data: string.as_ptr(), - } - } -} pub struct SimpleQObject {} #[derive(Clone)] pub struct SimpleEmitter { qobject: Arc>, message_changed: fn(*const SimpleQObject), } unsafe impl Send for SimpleEmitter {} impl SimpleEmitter { fn clear(&self) { *self.qobject.lock().unwrap() = null(); } pub fn message_changed(&self) { let ptr = *self.qobject.lock().unwrap(); if !ptr.is_null() { (self.message_changed)(ptr); } } } pub trait SimpleTrait { fn new(emit: SimpleEmitter) -> Self; fn emit(&self) -> &SimpleEmitter; fn message(&self) -> &str; fn set_message(&mut self, value: String); } #[no_mangle] pub extern "C" fn simple_new( simple: *mut SimpleQObject, message_changed: fn(*const SimpleQObject), ) -> *mut Simple { let simple_emit = SimpleEmitter { qobject: Arc::new(Mutex::new(simple)), message_changed: message_changed, }; let d_simple = Simple::new(simple_emit); Box::into_raw(Box::new(d_simple)) } #[no_mangle] pub unsafe extern "C" fn simple_free(ptr: *mut Simple) { Box::from_raw(ptr).emit().clear(); } #[no_mangle] -pub unsafe extern "C" fn simple_message_get( +pub extern "C" fn simple_message_get( ptr: *const Simple, p: *mut c_void, - set: fn(*mut c_void, QString), + set: fn(*mut c_void, *const c_char, c_int), ) { - let data = (&*ptr).message(); - set(p, data.into()); + let o = unsafe { &*ptr }; + let v = o.message(); + let s: *const c_char = v.as_ptr() as (*const c_char); + set(p, s, v.len() as c_int); } #[no_mangle] -pub unsafe extern "C" fn simple_message_set(ptr: *mut Simple, v: QStringIn) { - (&mut *ptr).set_message(v.convert()); +pub extern "C" fn simple_message_set(ptr: *mut Simple, v: *const c_ushort, len: c_int) { + let o = unsafe { &mut *ptr }; + let mut s = String::new(); + set_string_from_utf16(&mut s, v, len); + o.set_message(s); } diff --git a/templates/qt_quick/src/Bindings.cpp b/templates/qt_quick/src/Bindings.cpp index 7cf6e65..8178774 100644 --- a/templates/qt_quick/src/Bindings.cpp +++ b/templates/qt_quick/src/Bindings.cpp @@ -1,63 +1,50 @@ /* generated by rust_qt_binding_generator */ #include "Bindings.h" namespace { - struct qstring_t { - private: - const void* data; - int len; - public: - qstring_t(const QString& v): - data(static_cast(v.utf16())), - len(v.size()) { - } - operator QString() const { - return QString::fromUtf8(static_cast(data), len); - } - }; - typedef void (*qstring_set)(QString*, qstring_t*); - void set_qstring(QString* v, qstring_t* val) { - *v = *val; + typedef void (*qstring_set)(QString* val, const char* utf8, int nbytes); + void set_qstring(QString* val, const char* utf8, int nbytes) { + *val = QString::fromUtf8(utf8, nbytes); } inline void simpleMessageChanged(Simple* o) { emit o->messageChanged(); } } extern "C" { Simple::Private* simple_new(Simple*, void (*)(Simple*)); void simple_free(Simple::Private*); void simple_message_get(const Simple::Private*, QString*, qstring_set); - void simple_message_set(Simple::Private*, qstring_t); + void simple_message_set(Simple::Private*, const ushort *str, int len); }; Simple::Simple(bool /*owned*/, QObject *parent): QObject(parent), m_d(0), m_ownsPrivate(false) { } Simple::Simple(QObject *parent): QObject(parent), m_d(simple_new(this, simpleMessageChanged)), m_ownsPrivate(true) { } Simple::~Simple() { if (m_ownsPrivate) { simple_free(m_d); } } QString Simple::message() const { QString v; simple_message_get(m_d, &v, set_qstring); return v; } void Simple::setMessage(const QString& v) { - simple_message_set(m_d, v); + simple_message_set(m_d, reinterpret_cast(v.data()), v.size()); } diff --git a/templates/qt_widgets/rust/src/interface.rs b/templates/qt_widgets/rust/src/interface.rs index 9ddf376..da94277 100644 --- a/templates/qt_widgets/rust/src/interface.rs +++ b/templates/qt_widgets/rust/src/interface.rs @@ -1,110 +1,91 @@ /* generated by rust_qt_binding_generator */ #![allow(unknown_lints)] #![allow(mutex_atomic, needless_pass_by_value)] -use libc::{c_int, c_void, uint8_t, uint16_t}; +use libc::{c_char, c_ushort, c_int, c_void, uint8_t, uint16_t}; use std::slice; +use std::char::decode_utf16; use std::sync::{Arc, Mutex}; use std::ptr::null; use implementation::*; -#[repr(C)] -pub struct QString { - data: *const uint8_t, - len: c_int, -} - -#[repr(C)] -pub struct QStringIn { - data: *const uint16_t, - len: c_int, -} +pub enum QString {} -impl QStringIn { - fn convert(&self) -> String { - let data = unsafe { slice::from_raw_parts(self.data, self.len as usize) }; - String::from_utf16_lossy(data) - } +fn set_string_from_utf16(s: &mut String, str: *const c_ushort, len: c_int) { + let utf16 = unsafe { slice::from_raw_parts(str, len as usize) }; + let characters = decode_utf16(utf16.iter().cloned()) + .into_iter() + .map(|r| r.unwrap()); + s.clear(); + s.extend(characters); } -impl<'a> From<&'a str> for QString { - fn from(string: &'a str) -> QString { - QString { - len: string.len() as c_int, - data: string.as_ptr(), - } - } -} - -impl<'a> From<&'a String> for QString { - fn from(string: &'a String) -> QString { - QString { - len: string.len() as c_int, - data: string.as_ptr(), - } - } -} pub struct SimpleQObject {} #[derive(Clone)] pub struct SimpleEmitter { qobject: Arc>, message_changed: fn(*const SimpleQObject), } unsafe impl Send for SimpleEmitter {} impl SimpleEmitter { fn clear(&self) { *self.qobject.lock().unwrap() = null(); } pub fn message_changed(&self) { let ptr = *self.qobject.lock().unwrap(); if !ptr.is_null() { (self.message_changed)(ptr); } } } pub trait SimpleTrait { fn new(emit: SimpleEmitter) -> Self; fn emit(&self) -> &SimpleEmitter; fn message(&self) -> &str; fn set_message(&mut self, value: String); } #[no_mangle] pub extern "C" fn simple_new( simple: *mut SimpleQObject, message_changed: fn(*const SimpleQObject), ) -> *mut Simple { let simple_emit = SimpleEmitter { qobject: Arc::new(Mutex::new(simple)), message_changed: message_changed, }; let d_simple = Simple::new(simple_emit); Box::into_raw(Box::new(d_simple)) } #[no_mangle] pub unsafe extern "C" fn simple_free(ptr: *mut Simple) { Box::from_raw(ptr).emit().clear(); } #[no_mangle] -pub unsafe extern "C" fn simple_message_get( +pub extern "C" fn simple_message_get( ptr: *const Simple, p: *mut c_void, - set: fn(*mut c_void, QString), + set: fn(*mut c_void, *const c_char, c_int), ) { - let data = (&*ptr).message(); - set(p, data.into()); + let o = unsafe { &*ptr }; + let v = o.message(); + let s: *const c_char = v.as_ptr() as (*const c_char); + set(p, s, v.len() as c_int); } #[no_mangle] -pub unsafe extern "C" fn simple_message_set(ptr: *mut Simple, v: QStringIn) { - (&mut *ptr).set_message(v.convert()); +pub extern "C" fn simple_message_set(ptr: *mut Simple, v: *const c_ushort, len: c_int) { + let o = unsafe { &mut *ptr }; + let mut s = String::new(); + set_string_from_utf16(&mut s, v, len); + o.set_message(s); } diff --git a/templates/qt_widgets/src/Bindings.cpp b/templates/qt_widgets/src/Bindings.cpp index 7cf6e65..8178774 100644 --- a/templates/qt_widgets/src/Bindings.cpp +++ b/templates/qt_widgets/src/Bindings.cpp @@ -1,63 +1,50 @@ /* generated by rust_qt_binding_generator */ #include "Bindings.h" namespace { - struct qstring_t { - private: - const void* data; - int len; - public: - qstring_t(const QString& v): - data(static_cast(v.utf16())), - len(v.size()) { - } - operator QString() const { - return QString::fromUtf8(static_cast(data), len); - } - }; - typedef void (*qstring_set)(QString*, qstring_t*); - void set_qstring(QString* v, qstring_t* val) { - *v = *val; + typedef void (*qstring_set)(QString* val, const char* utf8, int nbytes); + void set_qstring(QString* val, const char* utf8, int nbytes) { + *val = QString::fromUtf8(utf8, nbytes); } inline void simpleMessageChanged(Simple* o) { emit o->messageChanged(); } } extern "C" { Simple::Private* simple_new(Simple*, void (*)(Simple*)); void simple_free(Simple::Private*); void simple_message_get(const Simple::Private*, QString*, qstring_set); - void simple_message_set(Simple::Private*, qstring_t); + void simple_message_set(Simple::Private*, const ushort *str, int len); }; Simple::Simple(bool /*owned*/, QObject *parent): QObject(parent), m_d(0), m_ownsPrivate(false) { } Simple::Simple(QObject *parent): QObject(parent), m_d(simple_new(this, simpleMessageChanged)), m_ownsPrivate(true) { } Simple::~Simple() { if (m_ownsPrivate) { simple_free(m_d); } } QString Simple::message() const { QString v; simple_message_get(m_d, &v, set_qstring); return v; } void Simple::setMessage(const QString& v) { - simple_message_set(m_d, v); + simple_message_set(m_d, reinterpret_cast(v.data()), v.size()); }