Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identify LVGL methods that return pointers #192

Open
C47D opened this issue Jan 15, 2025 · 2 comments
Open

Identify LVGL methods that return pointers #192

C47D opened this issue Jan 15, 2025 · 2 comments

Comments

@C47D
Copy link
Collaborator

C47D commented Jan 15, 2025

I'm not very fluent in Rust (still can't figure out ownership) but this change made lv_label_get_text available:

diff --git a/lvgl/src/widgets/label.rs b/lvgl/src/widgets/label.rs
index 691ffb8..5235f86 100644
--- a/lvgl/src/widgets/label.rs
+++ b/lvgl/src/widgets/label.rs
@@ -1,5 +1,6 @@
 use crate::widgets::Label;
 use crate::{LabelLongMode, NativeObject};
+use cstr_core::CStr;
 
 #[cfg(feature = "alloc")]
 mod alloc_imp {
@@ -41,4 +42,10 @@ impl Label<'_> {
     pub fn get_long_mode(&self) -> u8 {
         unsafe { lvgl_sys::lv_label_get_long_mode(self.raw().as_ref()) }
     }
+
+    pub fn get_text(&self) -> &'static str {
+        let char_ptr = unsafe { lvgl_sys::lv_label_get_text(self.raw().as_ref()) };
+        let c_str = unsafe { CStr::from_ptr(char_ptr) };
+        c_str.to_str().unwrap_or_default()
+    }
 }

And I'm using it like this

diff --git a/examples/demo.rs b/examples/demo.rs
index f69cf5b..dba4865 100644
--- a/examples/demo.rs
+++ b/examples/demo.rs
@@ -62,6 +62,8 @@ fn main() -> Result<(), LvError> {
     bt.set_height(80);
     bt.set_recolor(true);
     bt.set_align(Align::TopLeft, 0, 0);
+    let mut test_label = Label::from("701");
+    println!("Label get_text from bindinig: {:?}", test_label.get_text());
 
     let mut power: Label = "#fade2a 20%#".into();
     power.set_recolor(true);
diff --git a/lvgl/src/widgets/label.rs b/lvgl/src/widgets/label.rs
index 691ffb8..5235f86 100644
--- a/lvgl/src/widgets/label.rs
+++ b/lvgl/src/widgets/label.rs

You can see the '701' being printed here: image

Do you think this is correct @AlixANNERAUD ?

This is a memory safety issue, since get_text returns a &'static str, as it directly points to the label's text buffer, assuming the string is valid UTF-8.
However, when the label text is modified in LVGL, LVGL likely reallocates the buffer, invalidating the pointer/reference—this behavior contradicts the static reference lifetime.
To address this, the function should either be marked as unsafe (with appropriate documentation) or return an owned string instead. For instance:

String::from_utf8_lossy(cstr.to_bytes()).to_string()

Originally posted by @AlixANNERAUD in #162 (comment)

@C47D
Copy link
Collaborator Author

C47D commented Jan 15, 2025

We need to identify methods that return pointers so we either document them as unsafe or handle them properly. This might be possible by using the #191 request where adding support for generation of methods that return something is being handled.

What do you think @AlixANNERAUD ?

@AlixANNERAUD
Copy link
Collaborator

AlixANNERAUD commented Jan 15, 2025

Yes, that can be easily identified with syn::Type::Ptr. These should follow the same rules :

  • Try with zero copy / reference and safe way.
  • If not possible (eg label text where the lifetime is not guaranteed ), do it the unsafe way (zero copy). And maybe propose a safe with copy alternative

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants