[VOTE] Could you use LVGL if it were based on C++?

LVGL is good because its working on C. Just C. I am using it with stm32 (on C) and SBC`s (linux framebuffer on C)
As for me it will be more complicated to use (now lvgl can be ported on even door handle) and with c++ i think not.
Main thing i would improve - more widgets and less space requirement for projects.
Maybe i am !douing something wrong! but !full! library consumes 100kb of free space. And it forces me to find the way to use external memory where i dont want to.
if lvgl became mandatory c++, i will stay on last C version.
even if there some ugly places - they works fine, i like to work with this library - almost all seems on its places. Actually its the best product ive ever seen (usability), this library became most recent for me.

2 Likes

I see it the same way.

Wow, thank you! :heart_eyes:
Somehow in the past few days, I got unexpectedly many positive feedback. So happy. :slight_smile:

2 Likes

I have updated to v8 now and want to try emToile also. I’m using Mbed-OS, which has also a C++ API. Many objects have members that call C functions, because underlying frameworks are using C. I can see no big performance penalty, the compiler is optimizing a lot.
Lvgl. is using an OO approach already, but without type safety. You can call every function on a lv_obj, regardless if the object does support it or not. With C++ you create methods that work with a particular object and that makes it type safe. Another benefit is the Intellisense that can show the methods and properties of a widget.
For me, C++ is much more than syntactic sugar.

2 Likes

I definitely agree to have an optional C++ binding to LVGL but keep the core in C for maximal compatibility.

1 Like

that’s my C++ version in early stage GitHub - fstuff-dev/lvglpp: lvGL C++ Wrapper

Thanks, I commented here lvGL C++ Wrapper - #4 by kisvegabor

@kisvegabor, where is the code for this example https://www.youtube.com/watch?v=LpQ5-v_wig8?

1 Like

It’s a different topic but this video was created about the very first version of LVGL which wasn’t public and I’m not sure I still have it :smiley:

2 Likes

LVGL is supposing designed using C object orientation but from usability perspective, it’s far from a proper C++ API. For example, something I facing now while migrating to LVGL 8.x, I have a LVGL Label object and I want to find all the operations I can do on it. With C++ it would trivial using the IntelliSense code completion, but with the current LVGL API, it’s a long search in documentation and reverse engineering the code that is based on knowing relation between name prefixes (lv_obj applies also to lv_label) and on mysterious ‘parts’ enums that may or may not be related to the Label object. A search that often lead nothing.

A native C++ API will be a major step forward IMO, adopting more modern, productive, and maintainable coding practices.

Normally it should be all lv_obj_... and lv_label_... functions. Exactly what caused the headache?

With proper C++, to find the label operations I could type my_lable. and IntelliSense will resolve the inheritance and will show all the applicable methods. With the current LVGL, I need to know all the parent classes, their prefixes, and try each one of them with IntelliSense to see what comes up.

Same goes for contained objects, let’s say I type my_label. and see series(int), I continue with my_label.series(0). and intellisense will show me what is relevant for the server.

I think it reasonable to conclude that a more modern C++ API will be more user friendly and more productive. :wink: An I am not talking fancy things such as STL, and containers, just basic proper object oriented structures that modern tools and IDEs can understand.

I see. Have you seen this discussion on GitHub?

I was nor aware of it. Thanks.

I’ve ported many code from C to C++ in the last 10 years. From my experience, the C++ version is usually smaller, safer and faster. The C++ compiler is doing crazy optimizations that aren’t possible with C because of type erasing (the fact that the type becomes a void * breaks all future optimizations based on type deduction).

I’d like to correct few things in the discussion above:

  1. virtual table are not per instance, but per class (they are “static” pointer arrays in C++ terms). Since LVGL is doing its own pseudo virtual table based on string comparison to locate the right type, it’ll be more efficient to use C++ here
  2. C++ would allow removing the lv_ type prefix for each type, many, if not most of the get/set parameter. It’s a lot less method to remember / search for in the documentation.
  3. Making a C++ API on top of the C API is a bad idea, IMHO, since it’ll just bloat the binary. If the compiler breaks on void * in every method it enters, it’ll fail to inline, reuse, optimize as much as possible. That’s a bad news for “an easy” port, because it’ll just provide frustration (your port requires double work since you must duplicate all the C API and you get no gains). The right move, for me is to rewrite in C++ and rework a C api on top of the C++ code.
  4. Template, when used smartly (that is, not to make a hell of any maintainer, user) are very useful to help the compiler deduce the semantic of the code. If you look at this project I was able to construct a full MQTT v5 client in only 80kB of binary space (and 50kB on ESP32). For those you know about MQTT, it’s a protocol with variant type, many messages and properties. The best C solution are building at ~250kB and are slower by at least 2x.
    In that code, I used templates to generate all the common code for all different properties types (in LVGL, it would be all the common stuff of widgets) and a virtual inheritance just for the actual difference (with the goal of minimizing the binary space). The compiler is able to infer all the common part and remove virtual table for most classes so you don’t even pay a runtime cost for when the type used is only the child type. Also, it makes code size small and manageable (the entire client is ~5000 line of commented code). See here for the explanation of how this was done.
  5. The claimed “overload” of C++ standard library is wrong. Unless you actually need 1998’s stuff (like iostream and other initial dumbness), C++ standard library is most likely optimized away. I’m not using any STL stuff nor any RTTI in my ports so you don’t pay for what you don’t use.
  6. Type safety is one of the subtle place where C++ shines and where a C developer take a slap in the face with the lengthy compiler error message compared to the basic and wrong solution of casting everything to (void *). There is no solution to this but to learn to read those message and understand them. Sorry.
  7. Compile-time computation of many stuff is also a place where C++ shines. Every time you see a chain of strcmp(abc, "some text") in C, you’re killing a unicorn. In C++, compile-time string hashing is a reality so the O(N*M) algorithm above magically becomes a O(1) or O(N) algorithm. This also means a smaller binary since the some text string does not have to be stored in the binary anymore, only its hash value. Same goes for hash table, maps, and printf like stuff. You can even precompute CRC tables, ternary tree or even a C compiler that compile string-based C code at compile time.
  8. Debugging of C++ is a bit harder than C. But debugging LVGL is already a nightmare with all the type erasing (void *) everywhere, so in that specific case, I think it’ll be the same difficulty.
  9. Stack space requirement of C++ code is usually larger (since well written embedded C++ code does not use the heap that much or at all). That might or might not be an issue.
  10. Parsing C++ code by IDE used to be a lot worse than C. Now, with intellisence and clangd, it’s considered done. In the case of LVGL, it’ll be a lot better since, again, type erasure prevents code analyzer to deduce the actual interface of the objects. In C++ you’ll get all the class hierarchy in your IDE and not in the documentation.
  11. Generating binding with other languages will be harder in C++ than in C. C is the de facto lingua franca
  12. C++ is not harder to learn than C. You can limit yourself to only a small subset of C++. Class, basic template, namespaces, variant, and you will likely master all that’s required to build a performant code. No need to learn or understand the cryptic answer from C++ guru on stackoverflow, if you need those answers, your code is likely wrong anyway since it won’t be maintainable.
5 Likes

Thanks for this great summary. It was very informative.

I see the advantages of a C++ base with a C wrapper, but as the poll shows half of the users (at least who answered) need C. :frowning:
image

X-Ryl, You are right on every point, I agree with everything you said. I have only one thing to add. It’s not too difficult to build a good C binding to a C++ API (and with very little overhead), whereas (your point 3) the opposite is not true.

1 Like

In terms of the poll I am for LVGL remaining written in C for language binding reasons (aka the, I can use only C poll answer). Currently I am developing a series of Kotlin libraries that provide Kotlin bindings to LVGL/LV Drivers that are known as LVGL KT. Despite all of its faults the C language does have some advantages. Some of the advantages that are beneficial to language bindings are the following:

  1. Binary and source backwards compatibility (C++ has a poor backwards compatibility track record)
  2. Only a single variant of the C language (unlike C++ which is fragmented into many variants), which helps ensure backwards compatibility
  3. Easily portable to different platforms
  4. A huge number of platforms are supported
  5. Many high level languages support interop with C like Python, and Kotlin for example
  6. Lack of OO (Object Orientation) support makes it easier to develop some language bindings; especially for languages that don’t support OO (eg Lua)
1 Like

I note that you ignored my response to your false claims from two months ago, and instead you choose to repeat them here.

Number 1, 2, 3 and 4 draw a false boundary between C and C++. With regard to these items, there is no significant difference between C and C++. Your claim makes you seem a little inexperienced, or otherwise just biassed?

Support for interop and ease of developing bindings is somewhat better with C, no dispute. But C lacks many significant advantages of C++ also. C++ has some significant disadvantages that can be avoided by carefully choosing which features and libraries to ignore. But all this has been said before in this thread. You’re just choosing to ignore it.

@cjheath - Looking at your reply history you haven’t made any replies to my posts until today, which is the first time you have replied to a post I have made.

I would prefer C++ with its type safety, type safe enums, const expressions to reduce define use,…
Also you can eliminate a lot of the memory issues when using smart pointers to the objects and RAII. Those are all critical protections especially in embedded environments.
You can also reduce a lot of code duplication in a type safe way with the proper use of templates.
You can always add a C interface to the library for binding use.

We use C++ on STM32 MCU’s which have a decent ARM compiler.

2 Likes