<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>KDAB</title><description>Discover the depth of KDAB expertise in software. From Qt framework to C++ and Rust, from Operating Systems to GUI frameworks. From troubleshooting to complete project development. Get the software expertise you require to succeed.</description><link>https://www.kdab.com/</link><language>en-gb</language><item><title>Hotspot v1.6.0 released</title><link>https://www.kdab.com/hotspot-v1-6-0-released/</link><guid isPermaLink="true">https://www.kdab.com/hotspot-v1-6-0-released/</guid><description>&lt;p data-block-key=&quot;1sw01&quot;&gt;Hotspot is a standalone GUI designed to provide a user-friendly interface for analyzing performance data. It takes a perf.data file, parses and evaluates its contents, and presents the results in a visually appealing and easily understandable manner. Our goal with Hotspot is to offer a modern alternative to perf report, making performance analysis on Linux […]&lt;/p&gt;</description><pubDate>Fri, 13 Mar 2026 07:19:47 GMT</pubDate><content:encoded>&lt;h1&gt;Hotspot v1.6.0 released&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;3x6h0&quot;&gt;&lt;a href=&quot;https://www.kdab.com/hotspot-video/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Hotspot&lt;/a&gt; is a standalone GUI designed to provide a user-friendly interface for analyzing performance data. It takes a &lt;code&gt;perf.data&lt;/code&gt; file, parses and evaluates its contents, and presents the results in a visually appealing and easily understandable manner. Hotspot’s goal is to offer a modern alternative to &lt;code&gt;perf report&lt;/code&gt;, making performance analysis on Linux systems more intuitive and efficient.&lt;/p&gt;&lt;p data-block-key=&quot;c275l&quot;&gt;Version 1.6.0 introduces powerful new features, improved workflows, and numerous bug fixes to make profiling even smoother.&lt;/p&gt;&lt;h2 id=&quot;changelog-for-hotspot-v1.6.0&quot; data-block-key=&quot;39oj1&quot;&gt;ChangeLog for Hotspot v1.6.0&lt;/h2&gt;&lt;p data-block-key=&quot;duuev&quot;&gt;&lt;a href=&quot;https://github.com/KDAB/hotspot/releases/tag/v1.6.0&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;This release&lt;/a&gt; focuses on usability improvements and extended analysis capabilities. The most notable additions are:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;8eokv&quot;&gt;Support for archived perf files (e.g. &lt;code&gt;perf.data.zip&lt;/code&gt;)&lt;/li&gt;&lt;li data-block-key=&quot;6s6o4&quot;&gt;Regex filtering in the flamegraph&lt;/li&gt;&lt;li data-block-key=&quot;6dmsd&quot;&gt;Tracepoint support&lt;/li&gt;&lt;li data-block-key=&quot;fkvnu&quot;&gt;Various bug fixes and stability improvements&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;open-archived-perf-files-directly&quot; data-block-key=&quot;dw1a8&quot;&gt;Open Archived perf Files Directly&lt;/h2&gt;&lt;p data-block-key=&quot;7v5j4&quot;&gt;Hotspot can now open perf recordings stored inside archives such as &lt;code&gt;perf.data.zip&lt;/code&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;23rsk&quot;&gt;This simplifies sharing profiling results, storing CI artifacts, and working with compressed recordings - no manual extraction required.&lt;/p&gt;&lt;h2 id=&quot;regex-in-the-flamegraph&quot; data-block-key=&quot;hupsd&quot;&gt;Regex in the Flamegraph&lt;/h2&gt;&lt;p data-block-key=&quot;81umj&quot;&gt;The Flamegraph view now supports &lt;b&gt;regular expression filtering&lt;/b&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;2el70&quot;&gt;This makes it much easier to:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;gn9m&quot;&gt;Match complex symbol patterns&lt;/li&gt;&lt;li data-block-key=&quot;5m0p9&quot;&gt;Focus on specific subsystems or namespaces&lt;/li&gt;&lt;li data-block-key=&quot;1qokc&quot;&gt;Quickly narrow down large profiling datasets&lt;/li&gt;&lt;/ul&gt;&lt;p data-block-key=&quot;6s8g3&quot;&gt;Especially for large C++ codebases, regex search significantly speeds up navigation.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Hotspot_V1.6.0_Regex_Example&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Clipboard_-_March_3_2026_1_17_PM.original.png&quot; class=&quot;Hotspot_V1.6.0_Regex_Example&quot; alt=&quot;Hotspot_V1.6.0_Regex_Example&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;gcck3&quot;&gt;Regex in the flamegraph&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;tracepoint-support&quot; data-block-key=&quot;6ua5w&quot;&gt;Tracepoint Support&lt;/h2&gt;&lt;p data-block-key=&quot;243vm&quot;&gt;Hotspot 1.6.0 introduces support for &lt;b&gt;tracepoints&lt;/b&gt; captured via &lt;code&gt;perf&lt;/code&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;6ps2v&quot;&gt;This enables analysis of event-based data in addition to traditional sampling, giving deeper insight into system and runtime behavior.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Hotspot_V1.6.0_Tracepoints_Example&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Clipboard_-_March_3_2026_1_23_PM.original.png&quot; class=&quot;Hotspot_V1.6.0_Tracepoints_Example&quot; alt=&quot;Hotspot_V1.6.0_Tracepoints_Example&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;gcck3&quot;&gt;Tracepoints&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;bug-fixes-and-improvements&quot; data-block-key=&quot;2yvln&quot;&gt;Bug Fixes and Improvements&lt;/h2&gt;&lt;p data-block-key=&quot;eh5nf&quot;&gt;As usual, this release also includes numerous smaller fixes, UI refinements, and internal cleanups to improve overall stability and user experience.&lt;/p&gt;&lt;p data-block-key=&quot;a8i75&quot;&gt;For a complete overview of all changes, see the &lt;a href=&quot;https://github.com/KDAB/hotspot/releases/tag/v1.6.0&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;full changelog&lt;/a&gt; on GitHub.&lt;/p&gt;&lt;p data-block-key=&quot;csck&quot;&gt;Happy profiling!&lt;/p&gt;&lt;h2 id=&quot;videos&quot; data-block-key=&quot;uvkg0&quot;&gt;Videos&lt;/h2&gt;&lt;p data-block-key=&quot;dmlud&quot;&gt;Hotspot - A GUI for perf report:&lt;/p&gt;&lt;/div&gt;







&lt;div class=&quot;cookieconsent-optin-marketing overlay-embed-block&quot;&gt;
    &lt;div style=&quot;padding-bottom: 56.49999999999999%;&quot; class=&quot;responsive-object&quot;&gt;
    &lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/6ogEkQ-vKt4?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;Hotspot – A GUI for perf report&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;style&gt;
.overlay-embed-block .responsive-object {
    position: relative;
}

.overlay-embed-block .responsive-object iframe,
.overlay-embed-block .responsive-object object,
.overlay-embed-block .responsive-object embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
&lt;/style&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;3x6h0&quot;&gt;Hotspot Demo from Embedded World 2022:&lt;/p&gt;&lt;/div&gt;







&lt;div class=&quot;cookieconsent-optin-marketing overlay-embed-block&quot;&gt;
    &lt;div style=&quot;padding-bottom: 56.49999999999999%;&quot; class=&quot;responsive-object&quot;&gt;
    &lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/1_EOIsg89GA?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;Hotspot Demo&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;style&gt;
.overlay-embed-block .responsive-object {
    position: relative;
}

.overlay-embed-block .responsive-object iframe,
.overlay-embed-block .responsive-object object,
.overlay-embed-block .responsive-object embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
&lt;/style&gt;


&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/hotspot-v1-6-0-released/&quot;&gt;Hotspot v1.6.0 released&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Editor Team</dc:creator><category>c++</category><category>desktop</category><category>linux</category><category>open source</category><category>performance</category><category>tools</category><category>ux/ui</category></item><item><title>Weighing up Zngur and CXX for Rust/C++ Interop</title><link>https://www.kdab.com/weighing-up-zngur-and-cxx-for-rustc-interop/</link><guid isPermaLink="true">https://www.kdab.com/weighing-up-zngur-and-cxx-for-rustc-interop/</guid><description>&lt;p data-block-key=&quot;hga1v&quot;&gt;A detailed comparison of Zngur and CXX for Rust/C++ interoperability, exploring their design philosophies, container support, trait objects, async capabilities, build systems, and real-world tradeoffs.&lt;/p&gt;</description><pubDate>Thu, 05 Mar 2026 08:13:33 GMT</pubDate><content:encoded>&lt;h1&gt;Weighing up Zngur and CXX for Rust/C++ Interop&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;With Rust consistently proving itself as a good replacement for C++ due to its type system, memory safety, and macros, many industry giants are starting to write or rewrite things in this more modern systems language.&lt;/p&gt;&lt;p data-block-key=&quot;3t3l4&quot;&gt;That being said, the maturity, and broad ecosystem of C++ cannot be understated, and many companies have decades of code written in established C++ tech stacks, for example the Qt framework. This is where interoperability comes in, allowing Rust&apos;s modern features and package management to be paired with existing C++ knowledge and codebases, or call rigorously tested and optimised C++ libraries in a new Rust codebase.&lt;/p&gt;&lt;p data-block-key=&quot;bm1d0&quot;&gt;Now that &lt;a href=&quot;https://cxx.rs/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;CXX&lt;/a&gt; - the most widely adopted Rust with C++ interop library - is mature and kept very stable, we would like to explore &lt;a href=&quot;https://crates.io/crates/zngur&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Zngur&lt;/a&gt;, another emerging library in this space.&lt;/p&gt;&lt;h2 id=&quot;design-philosophies&quot; data-block-key=&quot;2kdtf&quot;&gt;Design Philosophies&lt;/h2&gt;&lt;p data-block-key=&quot;569hm&quot;&gt;One important differentiator between these libraries is their aims, with Zngur attempting to support a larger subset of semantics, with the cost of some performance, ergonomics and safety, whereas CXX preaches safety and a reduced feature set, with the claim of no overhead. As stated in the &lt;a href=&quot;https://hkalbasi.github.io/zngur/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Zngur documentation&lt;/a&gt;:&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;73p99&quot;&gt;&quot;Zngur also makes safety guarantees but also tries to be powerful enough to handle arbitrary signatures from Rust code&quot;&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;One example where Zngur is less restrictive than CXX is that it permits owned objects across the FFI boundary, using the &lt;code&gt;#cpp_value&lt;/code&gt; directive. Zngur also avoids guarantees around &lt;code&gt;Send&lt;/code&gt; and &lt;code&gt;Sync&lt;/code&gt; as we will discuss in the multithreading section.&lt;/p&gt;&lt;p data-block-key=&quot;dqtjq&quot;&gt;I personally found Zngur a little easier to set up, but it does have a more convoluted way of specifying the language boundary, which is explained below. Additionally, Zngur aims to keep most of the generated and glue code in the C++ side, as opposed to splitting it over Rust and C++, and this can potentially make it easier to debug, but also eschews some of Rust&apos;s safety guarantees. On the other hand, the many thousands of lines of C++ code can sometimes be redundant and difficult to search through.&lt;/p&gt;&lt;h2 id=&quot;technical-dive&quot; data-block-key=&quot;3oj06&quot;&gt;Technical Dive&lt;/h2&gt;&lt;p data-block-key=&quot;fjvcj&quot;&gt;Now let&apos;s get into the nitty-gritty details of this comparison that separate these two frameworks. Zngur poses some advantages over CXX with more arbitrary container support, and trait implementations with dynamic dispatch. On the other hand, CXX has a more solid build setup, much larger community, and external support for async Rust, all of which we will explore below.&lt;/p&gt;&lt;h3 id=&quot;containers&quot; data-block-key=&quot;8melw&quot;&gt;Containers&lt;/h3&gt;&lt;p data-block-key=&quot;cdp3l&quot;&gt;One of Zngur&apos;s selling points is its claim to support most container types with &quot;almost full API&quot;, whereas CXX has a more limited selection. Some of these types include nesting vectors such as &lt;code&gt;Vec&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;HashMap&amp;lt;K, V&amp;gt;&lt;/code&gt;, and &lt;code&gt;Arc&amp;lt;dyn T&amp;gt;&lt;/code&gt; (we will discuss trait objects next).&lt;/p&gt;&lt;p data-block-key=&quot;66uuk&quot;&gt;This first class support comes with a cost, however, as each type needs to be manually specified, e.g. &lt;code&gt;Vec&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt;&lt;/code&gt; and &lt;code&gt;Vec&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;&lt;/code&gt; need to be separately declared (and even &lt;code&gt;String&lt;/code&gt; needs to be declared). This quickly compounds, as for each type, you must specify all std library methods you want to use, which can lead to very large files.&lt;/p&gt;&lt;p data-block-key=&quot;d9u57&quot;&gt;CXX has good support for many container types with &quot;out of the box&quot; use, and more complex types can be wrapped with the newtype pattern, and used opaquely, with slightly reduced ergonomics. CXX also has the very powerful feature of being able to automatically generate the appropriate specializations for the types you need. In most cases, CXX has enough support for standard containers - and makes using them a lot simpler - but if your app is going to have a lot of complex types, you may be better going with Zngur.&lt;/p&gt;&lt;h4 id=&quot;nested-vectors-in-zngur&quot; data-block-key=&quot;6dxfa&quot;&gt;Nested Vectors in Zngur&lt;/h4&gt;&lt;p data-block-key=&quot;7a06u&quot;&gt;Here we have an example IDL (interface description language) file declaring a 2D vector. Zngur uses separate files for it&apos;s boundary description, whereas CXX has the bridge macro, but these perform the same role.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;// Exposes nested vector types
mod vec {
    type Vec&amp;lt;i32&amp;gt; {
        #layout(size = 24, align = 8);
        wellknown_traits(Debug);
        fn new() -&amp;gt; Vec&amp;lt;i32&amp;gt;;
        fn push(&amp;amp;mut self, i32);
        fn len(&amp;amp;self) -&amp;gt; usize;
    }

    type Vec&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt; {
        #layout(size = 24, align = 8);
        wellknown_traits(Debug);
        fn new() -&amp;gt; Vec&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt;;
        fn push(&amp;amp;mut self, Vec&amp;lt;i32&amp;gt;);
        fn len(&amp;amp;self) -&amp;gt; usize;
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/prelude.zng#L20-L45&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;See here for the full file&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;f0kb8&quot;&gt;We can construct, move, and call functions with the type in C++ like&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;auto row1 = to_vec({1,0,0});
auto row2 = to_vec({0,2,0});
auto row3 = to_vec({0,0,1});

auto matrix1 = Vec&amp;lt;Vec&amp;lt;int32_t&amp;gt;&amp;gt;::new_();
auto matrices = Vec&amp;lt;Vec&amp;lt;Vec&amp;lt;int32_t&amp;gt;&amp;gt;&amp;gt;::new_();

matrix1.push(std::move(row1));
matrix1.push(std::move(row2));
matrix1.push(std::move(row3));

matrices.push(std::move(matrix1));

zngur_dbg(rust::crate::determinants(matrices));&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/main.cpp#L47-L71&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;eu7j2&quot;&gt;The template has been declared in C++ to shorten &lt;code&gt;rust::std::vec::Vec&amp;lt;T&amp;gt;&lt;/code&gt;, and the &lt;code&gt;to_vec&lt;/code&gt; helper is used so rows can be created with initializer lists.&lt;/p&gt;&lt;p data-block-key=&quot;6ocai&quot;&gt;The Rust function is simply calculating matrix determinants, and performing this on a vector of matrices. This way we make use of 1D, 2D and 3D vectors across the boundary.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;/// Treating nested vector like a 3x3 matrix, returns list of 
pub fn determinants(matrices: &amp;amp;Vec&amp;lt;Vec&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt;&amp;gt;) -&amp;gt; Vec&amp;lt;i32&amp;gt; {
    let mut result = vec![];
    for m in matrices {
        // Naming components to make formula easier to read
        let a = m[0][0];
        // ...
        let i = m[2][2];

        let det = a*e*i + b*f*g + c*d*h - (c*e*g + a*f*h + b*d*i);
        result.push(det);
    }

    result
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/src/nested_types.rs#L4-L31&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;h4 id=&quot;nested-vectors-in-cxx&quot; data-block-key=&quot;bme3x&quot;&gt;Nested Vectors in CXX&lt;/h4&gt;&lt;p data-block-key=&quot;6hjo1&quot;&gt;CXX does not support bridging arbitrary containers, but this can easily be remedied using the newtype pattern. Although they must then be opaque, you can put more complex containers behind a struct, and pass that over the boundary, like so:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;// We define a newtype, and can give it some basic methods
#[derive(Debug)]
struct Matrix {
    inner: Vec&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt;,
}

impl Matrix {
    fn get_row(&amp;amp;self, row: usize) -&amp;gt; &amp;amp;Vec&amp;lt;i32&amp;gt; {
        &amp;amp;self.inner[row]
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/main.rs#L35-L44&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;73dkj&quot;&gt;And then adding some C++ code, we can use this newtype to perform some calculations&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// We use an app class to hold our methods
ExampleApp::ExampleApp() {}

std::unique_ptr&amp;lt;ExampleApp&amp;gt; new_app() {
  return std::unique_ptr&amp;lt;ExampleApp&amp;gt;(new ExampleApp());
}

// Calculating the determinants the same as the Zngur example
int32_t ExampleApp::calculate_determinant(const Matrix &amp;amp;m) const {
  auto row0 = m.get_row(0);
  auto row1 = m.get_row(1);
  auto row2 = m.get_row(2);
  
  // We can use the index operator, because CXX maps Rust Vec to C++ vector, something not possible in Zngur
  auto a = row0[0];
  // ...
  auto i = row2[2];

  auto det = a*e*i + b*f*g + c*d*h - (c*e*g + a*f*h + b*d*i);
  return det;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/example.cc#L5-L27&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;1ib1l&quot;&gt;We then specify the boundary using the CXX bridge macro:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;#[cxx::bridge]
mod ffi {
    extern &amp;quot;Rust&amp;quot; {
        type Matrix;
        fn get_row(self: &amp;amp;Matrix, row: usize) -&amp;gt; &amp;amp;Vec&amp;lt;i32&amp;gt;;
    }

    unsafe extern &amp;quot;C++&amp;quot; {
        include!(&amp;quot;cxx-example/include/example.h&amp;quot;);
        type ExampleApp;

        fn new_app() -&amp;gt; UniquePtr&amp;lt;ExampleApp&amp;gt;;
        fn calculate_determinant(&amp;amp;self, matrix: &amp;amp;Matrix) -&amp;gt; i32;
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/main.rs#L3-L16&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;s7hr&quot;&gt;This can then be called like so in our main function:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;fn main() {
    let app = ffi::new_app();
    let m = vec![vec![1, 2, 3], vec![4, 5, 0], vec![0, 0, 9]];
    let mat = Matrix { inner: m };
    let det = app.calculate_determinant(&amp;amp;mat);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/main.rs#L46-L52&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;cjfkh&quot;&gt;Although similar, both approaches have their strengths and weaknesses.&lt;/p&gt;&lt;h3 id=&quot;enums&quot; data-block-key=&quot;xbm0w&quot;&gt;Enums&lt;/h3&gt;&lt;p data-block-key=&quot;d2btp&quot;&gt;Whilst CXX has support for basic Rust enums, Zngur&apos;s built-in support for tagged union type enums (variants that contain data) is very powerful for Rust users.&lt;/p&gt;&lt;p data-block-key=&quot;5tsbq&quot;&gt;This means that defining &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; in your crate is trivial, and these are two of the most used data types in Rust. This includes constructors, e.g. instantiating &lt;code&gt;Ok(value)&lt;/code&gt; in C++ code. Of course, the developer still needs to specify that they want to use these types in the IDL file.&lt;/p&gt;&lt;p data-block-key=&quot;70kdn&quot;&gt;On the other hand, the CXX community has a solution for this, in that if you need support for more than basic enums, there exists &lt;a href=&quot;https://crates.io/crates/cxx-enumext&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;cxx-enumext&lt;/a&gt;, which provides the support for much more complex enums, including data with lifetimes, and boxed data. There is certainly something to be said for Zngur&apos;s wider support for declaring these algebraic data types, however.&lt;/p&gt;&lt;h3 id=&quot;traits&quot; data-block-key=&quot;cbn0m&quot;&gt;Traits&lt;/h3&gt;&lt;p data-block-key=&quot;dv0md&quot;&gt;Another strength of Zngur&apos;s is implementing traits in C++. For example, as a replacement for abstract classes or interfaces, you can define a Rust trait, and implement it in C++, for either Rust or C++ types, allowing polymorphism over the boundary via constructing a &lt;code&gt;Box&amp;lt;dyn MyTrait&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;d233c&quot;&gt;For example, as a replacement for abstract classes or interfaces, you have two options when it comes to traits:&lt;/p&gt;&lt;ol&gt;&lt;li data-block-key=&quot;c5ddp&quot;&gt;Implement your trait for &lt;b&gt;Rust&lt;/b&gt; objects using &lt;i&gt;C++&lt;/i&gt;&lt;/li&gt;&lt;li data-block-key=&quot;bbdqg&quot;&gt;Implement your trait for a &lt;i&gt;C++ class&lt;/i&gt;, by inheriting from it in &lt;i&gt;C++&lt;/i&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p data-block-key=&quot;70dov&quot;&gt;One caveat to this, however, is that Zngur provides a &lt;code&gt;make_box&lt;/code&gt; C++ helper for using these objects polymorphically, but is only accessible to C++ classes that inherit from a trait, not Rust objects with Rust or C++ implementations. This does, however, seem like something that could be easily rectified in the future. Our workaround for this, is simply adding a method to your trait like so:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;trait MyTrait {
    // Your trait methods here
    fn as_my_trait(self) -&amp;gt; Box&amp;lt;dyn MyTrait&amp;gt; where Self: Sized + &amp;#x27;static { 
        Box::new(self)
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;In CXX this type of behaviour would be done via a &lt;code&gt;UniquePtr&lt;/code&gt; instead and a C++ base class. This has its benefits and tradeoffs, but the first class support for trait objects in Zngur bodes well for leveraging the power that traits bring. Moreover, C++ lambdas can be turned into &lt;code&gt;Box&amp;lt;dyn Fn&amp;gt;&lt;/code&gt; objects, allowing them to be passed to Rust functions like &lt;code&gt;map&lt;/code&gt; like a Rust closure.&lt;/p&gt;&lt;p data-block-key=&quot;5ipef&quot;&gt;With this IDL definition:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;mod crate {
    // Declaring the methods we want to use in the trait
    trait MediaType {
        fn author(&amp;amp;self) -&amp;gt; ::std::string::String;
        fn title(&amp;amp;self) -&amp;gt; ::std::string::String;
        fn rating(&amp;amp;self) -&amp;gt; u8;
        fn media_type(&amp;amp;self) -&amp;gt; ::std::string::String;
    }

    // Box type must be declared too
    type Box&amp;lt;dyn crate::MediaType&amp;gt; {
        #layout(size = 16, align = 8);
    }

    // A rust function to display Movies, Songs, Albums, and any new media types
    // Simply prints out the author, title and rating in a pretty format
    fn display_media(Box&amp;lt;dyn MediaType&amp;gt;);

    type Movie {
        #layout(size = 56, align = 8);
        wellknown_traits(Debug);

        constructor {author_name: ::std::string::String, movie_title: ::std::string::String, movie_rating: u8};
        fn as_boxed(self) -&amp;gt; Box&amp;lt;dyn MediaType&amp;gt; use MediaType; // The use keyword specifies this method comes from the trait

        field author_name (offset = 0, type = ::std::string::String);
        field movie_title (offset = 24, type = ::std::string::String);
        field movie_rating (offset = 48, type = u8);
    }

    type Song {
        #layout(size = 56, align = 8);
        wellknown_traits(Debug);

        constructor {author: ::std::string::String, title: ::std::string::String, rating: u8};

        field author (offset = 0, type = ::std::string::String);
        field title (offset = 24, type = ::std::string::String);
        field rating (offset = 48, type = u8);
    }
}

// This block declares that we are going to implement the trait using C++
// This is done using the Impl template provided by Zngur
extern &amp;quot;C++&amp;quot; {
    impl crate::MediaType for crate::Movie {
        fn author(&amp;amp;self) -&amp;gt; ::std::string::String;
        fn title(&amp;amp;self) -&amp;gt; ::std::string::String;
        fn rating(&amp;amp;self) -&amp;gt; u8;
        fn media_type(&amp;amp;self) -&amp;gt; ::std::string::String;
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/trait_objects.zng&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full File Here&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;911qt&quot;&gt;We can implement traits for our Rust types using C++ like so&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// Trait impls
String
rust::Impl&amp;lt;Movie, MediaType&amp;gt;::author(
    rust::Ref&amp;lt;Movie&amp;gt; self) {
    // String have to be clone to be owned in C++ since they are allocated by the rust heap, so cannot be moved easily
  return self.author_name.clone();
}

String
rust::Impl&amp;lt;Movie, MediaType&amp;gt;::title(
    rust::Ref&amp;lt;Movie&amp;gt; self) {
  return self.movie_title.clone();
}

String
rust::Impl&amp;lt;Movie, MediaType&amp;gt;::media_type(
    rust::Ref&amp;lt;Movie&amp;gt; _self) {
  return &amp;quot;Cinema&amp;quot;_rs.to_owned();
}

uint8_t
rust::Impl&amp;lt;Movie, MediaType&amp;gt;::rating(
    rust::Ref&amp;lt;Movie&amp;gt; self) {
  return self.movie_rating;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/main.cpp#L93-L117&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;6a64d&quot;&gt;We can then access boxed trait objects in a few ways:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;28c8&quot;&gt;Inherit from the trait, and use the make_box helper&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// Implementing MediaType for rust::Song
class SongMedia : public MediaType {
  Song song;

public:
  SongMedia(Song s) : song(std::move(s)) {}

 ...
};

...

// Create an instance from a rust::Song
auto song_media = SongMedia(std::move(song));

// Call its methods
auto artist = song_media.author();
zngur_dbg(artist);

// Get a boxed trait object using the Zngur helper
auto boxed_song_media = Box&amp;lt;Dyn&amp;lt;MediaType&amp;gt;&amp;gt;::make_box&amp;lt;SongMedia&amp;gt;(std::move(song_media));
display_media(std::move(boxed_song_media));&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/main.cpp#L21-L45&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;2qcqe&quot;&gt;Use the rust trait implementation&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// Using the rust as_boxed method as shown above (called as_boxed here)
auto my_album_as_media_type = my_album.as_boxed();
display_media(std::move(my_album_as_media_type));&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;ul&gt;&lt;li data-block-key=&quot;oqsck&quot;&gt;Use the C++ trait implementation&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// display_media will use the C++ implentations, but note as_boxed comes from the trait in Rust.
auto my_movie_as_media_type = jaws.as_boxed();
display_media(std::move(my_movie_as_media_type));&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;mgy12&quot;&gt;Note that the trait contains an implemented method as_boxed, so C++ implementations can use it: &lt;code&gt;fn as_boxed(self) -&amp;gt; Box&amp;lt;dyn MediaType&amp;gt; where Self: Sized + &apos;static { Box::new(self) }&lt;/code&gt;&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;These 3 options permit flexible use of traits implemented in Rust or C++.&lt;/p&gt;&lt;p data-block-key=&quot;eqnbm&quot;&gt;In CXX, we use a different idiom, defining a base class, and then using &lt;code&gt;UniquePtr&lt;/code&gt; to get access to it in Rust.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// Abstract base / interface
class Media {
    public:
        virtual rust::String media_type() const = 0;
        virtual rust::String author() const = 0;
        virtual rust::String title() const = 0;
        virtual int rating() const = 0;
        const Media&amp;amp; as_media() const { return *this; }
};&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/include/media.h#L7-L14&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Complete Header File&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;cr465&quot;&gt;This acts as our &quot;trait&quot; since we need to override the virtual methods, and the as_media method is available on inheritors. It use the dereference in the return so that it can be coerced into the base class.&lt;/p&gt;&lt;p data-block-key=&quot;62qsa&quot;&gt;We can then define our inheriting classes:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;class Movie : public Media {
public:
    Movie(rust::String title, rust::String author, int rating) : m_title(std::move(title)), m_author(std::move(author)), m_rating(rating) {}
    rust::String author() const override {
        return m_author;
    }

    rust::String title() const override {
        return m_title;
    }

    rust::String media_type() const override {
        return rust::String(&amp;quot;Movie&amp;quot;);
    }

    int rating() const override {
        return m_rating;
    }

private:
    rust::String m_title;
    rust::String m_author;
    int m_rating;
};&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;And do the same for our Song class.&lt;/p&gt;&lt;p data-block-key=&quot;ep66v&quot;&gt;We can then define our methods to obtain a unique pointer:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;std::unique_ptr&amp;lt;Movie&amp;gt; make_movie(rust::String title, rust::String author, int rating) {
    return std::make_unique&amp;lt;Movie&amp;gt;(title, author, rating);
}

std::unique_ptr&amp;lt;Song&amp;gt; make_song(rust::String title, rust::String author, int rating) {
    return std::make_unique&amp;lt;Song&amp;gt;(title, author, rating);
}

// function to print all media types in a readable manner
void display_media(const Media&amp;amp; m) {
    ...
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/example.cc#L29-L44&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;30iv0&quot;&gt;We can then expose them in the bridge of the &lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/main.rs#L18-L32&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;main file&lt;/a&gt; like so:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;#[cxx::bridge]
mod ffi {
    unsafe extern &amp;quot;C++&amp;quot; {
        include!(&amp;quot;cxx-example/include/media.h&amp;quot;);

        type Media;
        type Movie;
        type Song;

        fn make_movie(title: String, author: String, rating: i32) -&amp;gt; UniquePtr&amp;lt;Movie&amp;gt;;
        fn make_song(title: String, author: String, rating: i32) -&amp;gt; UniquePtr&amp;lt;Song&amp;gt;;

        fn as_media(self: &amp;amp;Movie) -&amp;gt; &amp;amp;Media;
        fn as_media(self: &amp;amp;Song) -&amp;gt; &amp;amp;Media;

        fn display_media(m: &amp;amp;Media);
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;And use them in main,&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;fn main() {
    // Media
    let jaws = make_movie(&amp;quot;Jaws&amp;quot;.to_owned(), &amp;quot;Steven Spielberg&amp;quot;.to_owned(), 8);
    let fur_elise = make_song(&amp;quot;Fur Elise&amp;quot;.to_owned(), &amp;quot;Mozart&amp;quot;.to_owned(), 5);

    display_media(jaws.as_ref().unwrap().as_media());
    display_media(fur_elise.as_ref().unwrap().as_media());
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;async-and-threading&quot; data-block-key=&quot;izn2c&quot;&gt;Async and Threading&lt;/h3&gt;&lt;p data-block-key=&quot;a75ab&quot;&gt;On the other side of the coin, CXX has support for async rust &lt;a href=&quot;https://cxx.rs/async.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;planned&lt;/a&gt;, allowing async functions to be simply declared in the bridge, but currently they offer a workaround for calling async functions via a new type struct, containing a &lt;a href=&quot;https://docs.rs/futures/latest/futures/channel/oneshot/index.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;oneshot channel&lt;/a&gt; (futures crate). Furthermore, the &lt;a href=&quot;https://crates.io/crates/cxx-async&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;cxx-async&lt;/a&gt; crate adds support for async tasks, and is fairly well established, so it can be a robust addition to your project if you need async.&lt;/p&gt;&lt;p data-block-key=&quot;fqvm8&quot;&gt;Zngur on the other hand does not have this support planned, and makes no mention of how to implement it yourself. Zngur also doesn&apos;t do any checks, however, around &lt;code&gt;Send&lt;/code&gt; and &lt;code&gt;Sync&lt;/code&gt; - despite having support for &lt;code&gt;Arc&amp;lt;T&amp;gt;&lt;/code&gt; (a smart pointer used in threaded situations), as opposed to CXX&apos;s static assertions, which make multithreaded situations much safer.&lt;/p&gt;&lt;h3 id=&quot;project-setup&quot; data-block-key=&quot;2hkxt&quot;&gt;Project Setup&lt;/h3&gt;&lt;p data-block-key=&quot;17f46&quot;&gt;A further benefit of CXX is its significantly higher adoption - being used in Chromium and Android - as well as its better written and more complete documentation. We did find that Zngur had a slightly simpler project setup, being that you can simply generate the glue code, then use your existing C++ build setup, along with cargo to generate a library, or alternatively compile a C++ library, and link to your Rust binary. This independence from a specific build system makes it quick to integrate with what your already have. It also has the added benefit of not requiring any dependencies, simply being a CLI tool which generates the glue code for you.&lt;/p&gt;&lt;p data-block-key=&quot;6k31l&quot;&gt;As we have often seen with CXX throughout the blog, this functionality does exist in some form, namely the &lt;code&gt;cxxbridge&lt;/code&gt; command. This allows you to take a CXX bridge file, and manually generate the glue code.&lt;/p&gt;&lt;p data-block-key=&quot;begjh&quot;&gt;For Cargo builds, CXX recommends &lt;code&gt;cxx-build&lt;/code&gt; to obtain a CC builder, and the Zngur crate offers a builder struct to provide a similar CC interface, for building the glue code. Despite being harder to set up than the command line system, this offers deep configuration for more advanced use cases and could even allow combining Zngur with CXX. Corrosion also has experimental helpers for CXX builds with CMake (but there are no blockers on Zngur being supported here too in the future). Using a makefile or justfile to invoke build commands can also simplify the build process.&lt;/p&gt;&lt;p data-block-key=&quot;1pqlk&quot;&gt;An example &lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/build.rs&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Zngur build script&lt;/a&gt; for a simple project might look like this:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;use zngur::Zngur;

fn main() {
    build::rerun_if_changed(&amp;quot;main.zng&amp;quot;);
    build::rerun_if_changed(&amp;quot;prelude.zng&amp;quot;);
    build::rerun_if_changed(&amp;quot;trait_objects.zng&amp;quot;);
    build::rerun_if_changed(&amp;quot;nested_types.zng&amp;quot;);
    build::rerun_if_changed(&amp;quot;main.cpp&amp;quot;);
    build::rerun_if_changed(&amp;quot;nested_types.rs&amp;quot;);
    build::rerun_if_changed(&amp;quot;trait_objects.rs&amp;quot;);

    let crate_dir = build::cargo_manifest_dir();

    // Generate glue including the header, implementations (generated.cpp) and Rust code.
    Zngur::from_zng_file(crate_dir.join(&amp;quot;main.zng&amp;quot;))
        .with_cpp_file(crate_dir.join(&amp;quot;generated.cpp&amp;quot;))
        .with_h_file(crate_dir.join(&amp;quot;generated.h&amp;quot;))
        .with_rs_file(crate_dir.join(&amp;quot;./src/generated.rs&amp;quot;))
        .generate();

    let my_build = &amp;amp;mut cc::Build::new();
    let my_build = my_build.cpp(true).std(&amp;quot;c++17&amp;quot;);
    let my_build = || my_build.clone();

    // Build the C++ code using the CC builder, including the entrypoint to the program, and the generated impls
    my_build().file(&amp;quot;generated.cpp&amp;quot;).compile(&amp;quot;generated&amp;quot;);
    my_build().file(&amp;quot;main.cpp&amp;quot;).compile(&amp;quot;main&amp;quot;);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;In CXX a &lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/build.rs&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;build script&lt;/a&gt; looks very similar, since they both use the CC builder interface:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;fn main() {
    cxx_build::bridge(&amp;quot;src/main.rs&amp;quot;)
        .file(&amp;quot;src/example.cc&amp;quot;)
        .compile(&amp;quot;cxx-example&amp;quot;);

    println!(&amp;quot;cargo:rerun-if-changed=src/example.cc&amp;quot;);
    println!(&amp;quot;cargo:rerun-if-changed=include/example.h&amp;quot;);
    println!(&amp;quot;cargo:rerun-if-changed=include/media.h&amp;quot;);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;conclusion&quot; data-block-key=&quot;y9j0d&quot;&gt;Conclusion&lt;/h2&gt;&lt;p data-block-key=&quot;4p9dm&quot;&gt;As it stands at the minute, CXX definitely has stronger documentation, examples, and adoption, but remains to have strict rules around what gets added, and slow maintenance. Zngur offers a few benefits, but lacks key documentation, references of supported items, or even syntax. It does pose some interesting ideas which could be adopted by CXX, however, such as trait objects, and tagged unions (Rust enums which contain data, for example Option and Result). Although Zngur may be more time-consuming to write due to repeated definitions, we provide a custom prelude which you can place in your project, with any necessary basic types you may want, and this also includes a tool to generate any combination of these that you may want, see our tool &lt;a href=&quot;https://github.com/KDABLabs/zngur-prelude&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;zngur-prelude&lt;/a&gt; for more.&lt;/p&gt;&lt;p data-block-key=&quot;eg1do&quot;&gt;Some key differences in what is supported are laid out below:&lt;/p&gt;&lt;/div&gt;


&lt;table&gt;
    
    
        &lt;thead&gt;
            &lt;tr&gt;
                
                    
                        
                        
                            &lt;th scope=&quot;col&quot;  &gt;
                                
                                    
                                        Feature
                                    
                                
                            &lt;/th&gt;
                        
                    
                
                    
                        
                        
                            &lt;th scope=&quot;col&quot;  &gt;
                                
                                    
                                        CXX
                                    
                                
                            &lt;/th&gt;
                        
                    
                
                    
                        
                        
                            &lt;th scope=&quot;col&quot;  &gt;
                                
                                    
                                        Zngur
                                    
                                
                            &lt;/th&gt;
                        
                    
                
            &lt;/tr&gt;
        &lt;/thead&gt;
    
    &lt;tbody&gt;
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Generic Support
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Limited to built in types (listed below) when trying to define new generic types, e.g. no support for HashMap or Vec&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt; without a newtype wrapper.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Very broad support for defining Vec&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt;, HashMap&amp;lt;K, V&amp;gt;, Arc&amp;lt;dyn Trait&amp;gt;, with the caveat that each specialization needs to be defined manually.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Built In Support
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                CXX has built in support for Vec, String, UniquePtr, &amp;amp;[T] and a few others, and has strong guarantees about them.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Very limited built in support, not even supporting String or bool out of the box, but has very broad support for specifying these types yourself.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Trait Objects
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                No direct support for Box&amp;lt;dyn Trait&amp;gt;, Docs recommend using UniquePtr instead
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Full support: C++ types can implement Rust traits, and trait objects can be passed over the boundary.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Async Support
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Partial via cxx-async; integrates with Rust Future including futures crate.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                None yet. Can only emulate async via passing boxed function pointers and via channels.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Thread Safety
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Enforces Send and Sync requirements via static assertions.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                No assertions, but Mutex, Arc are supported.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Build System
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Integrated via cxx_build crate to support Cargo, CMake, and Bazel builds. Also has the cxxbridge tool to generate glue code from a file
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                CLI tool to generate glue code (zngur g file.zng) then manual build. Build scripts are supported but less so, with lesser adoption.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Documentation Status
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Mature, comprehensive docs at cxx.rs.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Sparse and incomplete, examples can be found in GitHub but they are limited.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Adoption
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Widely used, including in large projects like Chromium and Android.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Early adoption, Adobe seems to have taken an interest.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Overhead
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Zero-overhead abstraction, no serialization or copying.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Slight overhead possible; prioritizes flexibility and expressiveness.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Language Definition
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Inline within #[cxx::bridge] macro in the main Rust file.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Specified in an IDL file (.zng).
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Best Use
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Stable, performant FFI, integration with CXX-Qt, projects with simple types at the boundary
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Research, quick prototyping, or projects making strong use of Traits and dynamic dispatch in Rust. Easier to integrate into an existing C++ project
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
    &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;Choose CXX if your team needs proven safety, documentation, and tooling integration. Choose Zngur if you’re exploring advanced polymorphism or container-heavy data flows and are comfortable managing ABI stability yourself.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/weighing-up-zngur-and-cxx-for-rustc-interop/&quot;&gt;Weighing up Zngur and CXX for Rust/C++ Interop&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>c++</category><category>labs</category><category>open source</category><category>rust</category><category>tools</category></item><item><title>Automating Repetitive GUI Interactions in Embedded Development with Spix</title><link>https://www.kdab.com/automating-repetitive-gui-interactions-in-embedded-development-with-spix/</link><guid isPermaLink="true">https://www.kdab.com/automating-repetitive-gui-interactions-in-embedded-development-with-spix/</guid><description>&lt;p data-block-key=&quot;k9ick&quot;&gt;This blog post showcases Spix, a small but useful library for automating GUI-interaction in your Qt/QML-based applications. Just sending clicks or entering text to checking properties, Spix offers basic automated interaction. Combining the automated screenshot function with computer vision, you can even perform simple optical checks with Spix.&lt;/p&gt;</description><pubDate>Thu, 19 Feb 2026 08:18:12 GMT</pubDate><content:encoded>&lt;h1&gt;Automating Repetitive GUI Interactions in Embedded Development with Spix&lt;/h1&gt;
&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot;&gt;
        &lt;div class=&quot;image-variable-size-image&quot;&gt;
            &lt;img src=&quot;https://www.kdab.com/documents/2023-07-05-18-08-38-small_1.gif&quot; alt=&quot;2023-07-05-18-08-38-small_Blog_Christoph_Spix&quot;&gt;
        &lt;/div&gt;

        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;r7hie&quot;&gt;As Embedded Software Developers, we all know the pain: you make a code change, rebuild your project, restart the application - and then spend precious seconds repeating the same five clicks just to reach the screen you want to test. Add a login dialog on top of it, and suddenly those seconds turn into minutes. Multiply that by a hundred iterations per day, and it’s clear: this workflow is frustrating, error-prone, and a waste of valuable development time.&lt;/p&gt;&lt;p data-block-key=&quot;5kds4&quot;&gt;In this article, we’ll look at how to automate these repetitive steps using &lt;a href=&quot;https://github.com/faaxm/spix&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Spix&lt;/a&gt;, an open-source tool for GUI automation in Qt/QML applications. We’ll cover setup, usage scenarios, and how Spix can be integrated into your workflow to save hours of clicking, typing, and waiting.&lt;/p&gt;&lt;h2 id=&quot;the-problem:-click-fatigue-in-gui-testing&quot; data-block-key=&quot;ght5m&quot;&gt;The Problem: Click Fatigue in GUI Testing&lt;/h2&gt;&lt;p data-block-key=&quot;djqar&quot;&gt;Imagine this:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;1tiuj&quot;&gt;You start your application.&lt;/li&gt;&lt;li data-block-key=&quot;4ths2&quot;&gt;The login screen appears.&lt;/li&gt;&lt;li data-block-key=&quot;dii9m&quot;&gt;You enter your username and password.&lt;/li&gt;&lt;li data-block-key=&quot;d80kp&quot;&gt;You click &quot;Login&quot;.&lt;/li&gt;&lt;li data-block-key=&quot;78ntm&quot;&gt;Only then do you finally reach the UI where you can verify whether your code changes worked.&lt;/li&gt;&lt;/ul&gt;&lt;p data-block-key=&quot;9hpm3&quot;&gt;This is fine the first few times - but if you’re doing it 100+ times a day, it becomes a serious bottleneck. While features like &lt;b&gt;hot reload&lt;/b&gt; can help in some cases, they aren’t always applicable - especially when structural changes are involved or when you must work with &quot;real&quot; production data.&lt;/p&gt;&lt;p data-block-key=&quot;1mabg&quot;&gt;So, what’s the alternative?&lt;/p&gt;&lt;h2 id=&quot;the-solution:-automating-gui-input-with-spix&quot; data-block-key=&quot;3ymr9&quot;&gt;The Solution: Automating GUI Input with Spix&lt;/h2&gt;&lt;p data-block-key=&quot;5e5pv&quot;&gt;&lt;a href=&quot;https://github.com/faaxm/spix&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Spix&lt;/a&gt; allows you to control your Qt/QML applications programmatically. Using scripts (typically Python), you can automatically:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;76u3q&quot;&gt;Insert text into input fields&lt;/li&gt;&lt;li data-block-key=&quot;eajkm&quot;&gt;Click buttons&lt;/li&gt;&lt;li data-block-key=&quot;699mb&quot;&gt;Wait for UI elements to appear&lt;/li&gt;&lt;li data-block-key=&quot;c7j6r&quot;&gt;Take and compare screenshots&lt;/li&gt;&lt;/ul&gt;&lt;p data-block-key=&quot;e3mi6&quot;&gt;This means you can automate login steps, set up UI states consistently, and even extend your CI pipeline with &lt;b&gt;visual testing&lt;/b&gt;. Unlike manual hot reload tweaks or hardcoding start screens, Spix provides an &lt;b&gt;external, scriptable solution&lt;/b&gt; without altering your application logic.&lt;/p&gt;&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;setting-up-spix-in-your-project&quot; data-block-key=&quot;awzjs&quot;&gt;Setting up Spix in Your Project&lt;/h2&gt;&lt;p data-block-key=&quot;bu5nk&quot;&gt;Getting Spix integrated requires a few straightforward steps:&lt;/p&gt;&lt;h3 id=&quot;1.-add-spix-as-a-dependency&quot; data-block-key=&quot;pp4qw&quot;&gt;1. &lt;b&gt;Add Spix as a dependency&lt;/b&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;cs1gu&quot;&gt;Typically done via a Git submodule into your project’s third-party folder.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-bash  line-numbers &quot;&gt;git submodule add 3rdparty/spix git@github.com:faaxm/spix.git&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;2.-register-spix-in-cmake&quot; data-block-key=&quot;swc4s&quot;&gt;2.&lt;b&gt; Register Spix in CMake&lt;/b&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;78qpm&quot;&gt;Update your &lt;code&gt;CMakeLists.txt&lt;/code&gt; with a &lt;code&gt;find_package(Spix REQUIRED)&lt;/code&gt; call.&lt;/li&gt;&lt;li data-block-key=&quot;5ec9b&quot;&gt;Because of CMake quirks, you may also need to manually specify the path to Spix’s CMake modules.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cmake  line-numbers &quot;&gt;LIST(APPEND CMAKE_MODULE_PATH /home/christoph/KDAB/spix/cmake/modules)
find_package(Spix REQUIRED)&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;3.-link-against-spix&quot; data-block-key=&quot;m3xad&quot;&gt;3.&lt;b&gt; Link against Spix&lt;/b&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;7cv8c&quot;&gt;Add &lt;code&gt;Spix&lt;/code&gt; to your &lt;code&gt;target_link_libraries&lt;/code&gt; call.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cmake  line-numbers &quot;&gt;target_link_libraries(myApp
  PRIVATE Qt6::Core
          Qt6::Quick 
          Qt6::SerialPort 
          Spix::Spix
)&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;4.-initialize-spix-in-your-application&quot; data-block-key=&quot;odvmk&quot;&gt;4.&lt;b&gt; Initialize Spix in your application&lt;/b&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;1q365&quot;&gt;Include Spix headers in &lt;code&gt;main.cpp&lt;/code&gt;.&lt;/li&gt;&lt;li data-block-key=&quot;d95bc&quot;&gt;Add some lines of boilerplate code:&lt;ul&gt;&lt;li data-block-key=&quot;2ljlr&quot;&gt;Include the 2 Spix Headers (AnyRPCServer for Communication and QtQmlBot)&lt;/li&gt;&lt;li data-block-key=&quot;b2ora&quot;&gt;Start the Spix RPC server.&lt;/li&gt;&lt;li data-block-key=&quot;d3th0&quot;&gt;Create a &lt;code&gt;Spix::QtQmlBot&lt;/code&gt;.&lt;/li&gt;&lt;li data-block-key=&quot;7rom3&quot;&gt;Run the test server on a specified port (e.g. &lt;code&gt;9000&lt;/code&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;#include &amp;lt;Spix/AnyRpcServer.h&amp;gt;
#include &amp;lt;Spix/QtQmlBot.h&amp;gt;
[...]

//Start the actual Runner/Server
spix::AnyRpcServer server;
auto bot = new spix::QtQmlBot();
bot-&amp;gt;runTestServer(server);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;idubt&quot;&gt;At this point, your application is &quot;Spix-enabled&quot;. You can verify this by checking for the open port (e.g. &lt;code&gt;localhost:9000&lt;/code&gt;).&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;or7ol&quot;&gt;Spix can be a Security Risk: Make sure to not expose Spix in any production environment, maybe only enable it for your Debug-builds.&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;where-spix-shines&quot; data-block-key=&quot;c0rsv&quot;&gt;Where Spix Shines&lt;/h2&gt;&lt;p data-block-key=&quot;5fkof&quot;&gt;Once the setup is done, Spix can be used to automate repetitive tasks. Let’s look at two particularly useful examples:&lt;/p&gt;&lt;h3 id=&quot;1.-automating-logins-with-a-python-script&quot; data-block-key=&quot;0n0mj&quot;&gt;1. Automating Logins with a Python Script&lt;/h3&gt;&lt;p data-block-key=&quot;38fq4&quot;&gt;Instead of typing your credentials and clicking &quot;Login&quot; manually, you can write a simple Python script that:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;fvros&quot;&gt;Connects to the Spix server on &lt;code&gt;localhost:9000&lt;/code&gt;&lt;/li&gt;&lt;li data-block-key=&quot;f286n&quot;&gt;Inputs text into the &lt;code&gt;userField&lt;/code&gt; and &lt;code&gt;passwordField&lt;/code&gt;&lt;/li&gt;&lt;li data-block-key=&quot;9ft5u&quot;&gt;Clicks the &quot;Login&quot; button (Items marked with &quot;Quotes&quot; are literal That-Specific-Text-Identifiers for Spix)&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-python  line-numbers &quot;&gt;import xmlrpc.client

session = xmlrpc.client.ServerProxy(&amp;#x27;http://localhost:9000&amp;#x27;)

session.inputText(&amp;#x27;mainWindow/userField&amp;#x27;, &amp;#x27;christoph&amp;#x27;)
session.inputText(&amp;#x27;mainWindow/passwordField&amp;#x27;, &amp;#x27;secret&amp;#x27;) 
session.mouseClick(&amp;#x27;mainWindow/&amp;quot;Login&amp;quot;&amp;#x27;)&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;6qw4v&quot;&gt;When executed, this script takes care of the entire login flow - no typing, no clicking, no wasted time. Better yet, you can check the script into your repository, so your whole team can reuse it.&lt;/p&gt;&lt;p data-block-key=&quot;f3qad&quot;&gt;For Development, Integration in Qt-Creator can be achieved with a Custom startup executable, that also starts this python script.&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;yoeyx&quot;&gt;In a CI environment, this approach is particularly powerful, since you can ensure every test run starts from a clean state without relying on manual navigation.&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;2.-screenshot-comparison&quot; data-block-key=&quot;fzpkt&quot;&gt;2. Screenshot Comparison&lt;/h3&gt;&lt;p data-block-key=&quot;bf9dk&quot;&gt;Beyond input automation, Spix also supports &lt;b&gt;taking screenshots&lt;/b&gt;. Combined with Python libraries like OpenCV or &lt;code&gt;scikit-image&lt;/code&gt;, this opens up interesting possibilities for testing.&lt;/p&gt;&lt;h4 id=&quot;example-1:-full-screen-comparison&quot; data-block-key=&quot;ovfo0&quot;&gt;Example 1: Full-screen comparison&lt;/h4&gt;&lt;p data-block-key=&quot;4n3v3&quot;&gt;Take a screenshot of the main window and store it first:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-python  line-numbers &quot;&gt;import xmlrpc.client

session = xmlrpc.client.ServerProxy(&amp;#x27;http://localhost:9000&amp;#x27;)

[...]
session.takeScreenshot(&amp;#x27;mainWindow&amp;#x27;, &amp;#x27;/tmp/screenshot.png&amp;#x27;)k&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;6qw4v&quot;&gt;Now we can compare it with a reference image:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-python  line-numbers &quot;&gt;from skimage import io
from skimage.metrics import structural_similarity as ssim

screenshot1 = io.imread(&amp;#x27;/tmp/reference.png&amp;#x27;, as_gray=True)
screenshot2 = io.imread(&amp;#x27;/tmp/screenshot.png&amp;#x27;, as_gray=True)

ssim_index = ssim(screenshot1, screenshot2, data_range=screenshot1.max() - screenshot1.min())

threshold = 0.95

if ssim_index == 1.0: 
    print(&amp;quot;The screenshots are a perfect match&amp;quot;)
elif ssim_index &amp;gt;= threshold:
    print(&amp;quot;The screenshots are similar, similarity: &amp;quot; + str(ssim_index * 100) + &amp;quot;%&amp;quot;)
else:
    print(&amp;quot;The screenshots are not similar at all, similarity: &amp;quot; + str(ssim_index * 100) + &amp;quot;%&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;6qw4v&quot;&gt;This is useful for catching unexpected regressions in visual layout.&lt;/p&gt;&lt;h4 id=&quot;example-2:-finding-differences-in-the-same-ui&quot; data-block-key=&quot;0zrg1&quot;&gt;Example 2: Finding differences in the same UI&lt;/h4&gt;&lt;p data-block-key=&quot;fsbra&quot;&gt;Use OpenCV to highlight pixel-level differences between two screenshots—for instance, missing or misaligned elements:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-python  line-numbers &quot;&gt;import cv2

image1 = cv2.imread(&amp;#x27;/tmp/reference.png&amp;#x27;)
image2 = cv2.imread(&amp;#x27;/tmp/screenshot.png&amp;#x27;)

diff = cv2.absdiff(image1, image2)

# Convert the difference image to grayscale
gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)

# Threshold the grayscale image to get a binary image
_, thresh = cv2.threshold(gray, 30, 255, cv2.THRESH_BINARY)

contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(image1, contours, -1, (0, 0, 255), 2)

cv2.imshow(&amp;#x27;Difference Image&amp;#x27;, image1)
cv2.waitKey(0)&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;6qw4v&quot;&gt;This form of &lt;b&gt;visual regression testing&lt;/b&gt; can be integrated into your CI system. If the UI changes unintentionally, Spix can detect it and trigger an alert.&lt;/p&gt;&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;1024-637_Blog_Christoph_Spix&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/1024-637_1.original.png&quot; class=&quot;1024-637_Blog_Christoph_Spix&quot; alt=&quot;1024-637_Blog_Christoph_Spix&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;2759c&quot;&gt;Defective Image&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;1024-639_Blog_Christoph_Spix&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/1024-639_1.original.png&quot; class=&quot;1024-639_Blog_Christoph_Spix&quot; alt=&quot;1024-639_Blog_Christoph_Spix&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;2759c&quot;&gt;The script marked the defective parts of the image compared to the should-be image.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;recap&quot; data-block-key=&quot;j3bi4&quot;&gt;Recap&lt;/h2&gt;&lt;p data-block-key=&quot;398cv&quot;&gt;&lt;a href=&quot;https://github.com/faaxm/spix&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Spix&lt;/a&gt; is not a full-blown GUI testing framework like Squish, but it fills a useful niche for embedded developers who want to:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;30u8&quot;&gt;Save time on repetitive input (like logins).&lt;/li&gt;&lt;li data-block-key=&quot;2l6p7&quot;&gt;Share reproducible setup scripts with colleagues.&lt;/li&gt;&lt;li data-block-key=&quot;ba5ar&quot;&gt;Perform lightweight visual regression testing in CI.&lt;/li&gt;&lt;li data-block-key=&quot;3s1sr&quot;&gt;Interact with their applications on embedded devices remotely.&lt;/li&gt;&lt;/ul&gt;&lt;p data-block-key=&quot;9as1q&quot;&gt;While there are limitations (e.g. manual wait times, lack of deep synchronization with UI states), Spix provides a powerful and flexible way to automate everyday development tasks - without having to alter your application logic.&lt;/p&gt;&lt;p data-block-key=&quot;8pqgh&quot;&gt;If you’re tired of clicking the same buttons all day, give Spix a try. It might just save you hours of time and frustration in your embedded development workflow.&lt;/p&gt;&lt;/div&gt;







&lt;div class=&quot;cookieconsent-optin-marketing overlay-embed-block&quot;&gt;
    &lt;div style=&quot;padding-bottom: 56.49999999999999%;&quot; class=&quot;responsive-object&quot;&gt;
    &lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/WTYl4wHL0NI?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;GUI Automation and Testing with Spix&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;style&gt;
.overlay-embed-block .responsive-object {
    position: relative;
}

.overlay-embed-block .responsive-object iframe,
.overlay-embed-block .responsive-object object,
.overlay-embed-block .responsive-object embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
&lt;/style&gt;


&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/automating-repetitive-gui-interactions-in-embedded-development-with-spix/&quot;&gt;Automating Repetitive GUI Interactions in Embedded Development with Spix&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>python</category><category>qt</category><category>tools</category></item><item><title>KDAB at Embedded World 2026, Nuremberg, Germany</title><link>https://www.kdab.com/kdab-at-embedded-world-2026-nuremberg-germany/</link><guid isPermaLink="true">https://www.kdab.com/kdab-at-embedded-world-2026-nuremberg-germany/</guid><description>&lt;p data-block-key=&quot;s1l6s&quot;&gt;KDAB will be exhibiting at &lt;b&gt;Embedded World&lt;/b&gt; from &lt;b&gt;March, 10th through 12th, 2026&lt;/b&gt;, in Nuremberg, Germany.&lt;/p&gt;</description><pubDate>Tue, 17 Feb 2026 08:08:00 GMT</pubDate><content:encoded>&lt;h1&gt;KDAB at Embedded World 2026, Nuremberg, Germany&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;p828o&quot;&gt;At &lt;a href=&quot;https://www.embedded-world.de/en&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;Embedded World 2026&lt;/b&gt;&lt;/a&gt;, KDAB will showcase how we help customers build robust, high-performance embedded software using &lt;b&gt;Qt, C++, Rust, Slint, and Flutter&lt;/b&gt;. From multi-display streaming and real-time 3D UIs to developer tooling and continuous integration on real hardware, our booth will feature hands-on demos that reflect the challenges of embedded systems.&lt;/p&gt;&lt;p data-block-key=&quot;9c5qi&quot;&gt;Visit our booth 4-302 to experience the demos live and talk to our engineers about your project.&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;31ry2&quot;&gt;📍 Nuremberg, Germany&lt;br/&gt;📅 March 10–12, 2026&lt;br/&gt;📍 KDAB Booth: 4-302&lt;/p&gt;&lt;p data-block-key=&quot;eamq&quot;&gt;Get your tickets &lt;a href=&quot;https://www.messe-ticket.de/Nuernberg_SHOP/embeddedworld2026/Shop&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;migration-and-modernization-services&quot; data-block-key=&quot;vfnrl&quot;&gt;Migration and Modernization Services&lt;/h2&gt;&lt;p data-block-key=&quot;4v3r0&quot;&gt;KDAB helps customers transition legacy systems - whether that means moving from &lt;b&gt;Windows CE to Embedded Linux&lt;/b&gt; or &lt;b&gt;upgrading an existing software stack&lt;/b&gt;. This includes advanced code migration and tooling, as well as setting up complete embedded Linux environments with technologies such as &lt;b&gt;Yocto&lt;/b&gt; or &lt;b&gt;Torizon&lt;/b&gt;, tailored to the target hardware.&lt;/p&gt;&lt;p data-block-key=&quot;a3ga4&quot;&gt;For teams planning the move from Windows CE, there is a brand new guide on migrating to Embedded Linux, outlining key challenges, architecture considerations, and best‑practice workflows in detail. &lt;a href=&quot;https://www.kdab.com/windowsce-to-embedded-linux-migration/&quot;&gt;Read it here&lt;/a&gt; or pick it up at our booth in Hall 4, Booth 302 at Embedded World.&lt;/p&gt;&lt;p data-block-key=&quot;25tiv&quot;&gt;Beyond Windows Embedded migrations, KDAB offers expertise in a wide range of modernization projects, including &lt;a href=&quot;https://www.kdab.com/services/qt-services/qt-5-to-qt-6-migration-services/&quot;&gt;Qt 5 to Qt 6 migrations&lt;/a&gt;, &lt;a href=&quot;https://www.kdab.com/services/software-consulting/legacy-framework-migration/&quot;&gt;legacy framework transitions&lt;/a&gt;, and broader codebase and platform modernization efforts.&lt;/p&gt;&lt;h2 id=&quot;rugged-controller-for-arx-gereon-rcs&quot; data-block-key=&quot;asvm8&quot;&gt;Rugged Controller for ARX Gereon RCS&lt;/h2&gt;&lt;h3 id=&quot;kdab-designed-and-built-a-ui-for-robotic-platform-and-payload-control&quot; data-block-key=&quot;nkzbl&quot;&gt;KDAB Designed and Built a UI for Robotic Platform &amp;amp; Payload Control&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;5n24a&quot;&gt;UI built using Qt 6 and QML&lt;/li&gt;&lt;li data-block-key=&quot;1gsi0&quot;&gt;GStreamer for camera video playback&lt;/li&gt;&lt;li data-block-key=&quot;ctd1t&quot;&gt;Controller &amp;lt;-&amp;gt; Robot communication over multiple networks&lt;/li&gt;&lt;li data-block-key=&quot;6r3fn&quot;&gt;Oﬄine autonomous mapping support&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-33 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://www.arx-robotics.com/&quot; title=&quot;Logos_ARX&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_ARX&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_ARX.original.png&quot; class=&quot;Logos_ARX&quot; alt=&quot;Logos_ARX&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;live-3d-ui-for-autonomous-public-transport&quot; data-block-key=&quot;9c0sp&quot;&gt;Live 3D UI for Autonomous Public Transport&lt;/h2&gt;&lt;ul&gt;&lt;li data-block-key=&quot;7f51k&quot;&gt;Autonomous bus driven by Motor AI infrastructure&lt;/li&gt;&lt;li data-block-key=&quot;7m52i&quot;&gt;Interactive 3D dashboard&lt;/li&gt;&lt;li data-block-key=&quot;113m&quot;&gt;Real-time data streamed via MQTT&lt;/li&gt;&lt;li data-block-key=&quot;49urg&quot;&gt;Touch interface built with Slint&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-50 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://www.motor-ai.com/&quot; title=&quot;Logos_MotorAI&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_MotorAI&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_MotorAI.original.png&quot; class=&quot;Logos_MotorAI&quot; alt=&quot;Logos_MotorAI&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-50 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://slint.dev/&quot; title=&quot;Logos_Slint&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_Slint&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_Slint.original.png&quot; class=&quot;Logos_Slint&quot; alt=&quot;Logos_Slint&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;qt-gstreamer-multi-display-demo&quot; data-block-key=&quot;9zrio&quot;&gt;Qt GStreamer Multi-Display Demo&lt;/h2&gt;&lt;h3 id=&quot;stream-qt-applications-to-multiple-browser-instances&quot; data-block-key=&quot;2ftdo&quot;&gt;Stream Qt Applications to Multiple Browser Instances&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;8mjae&quot;&gt;Standard Qt/QML Application on an Intel Atom-based CPU&lt;/li&gt;&lt;li data-block-key=&quot;9erec&quot;&gt;Complex GStreamer pipeline to transform into a WebRTC stream&lt;/li&gt;&lt;li data-block-key=&quot;br582&quot;&gt;Improved the GStreamer plugin&lt;/li&gt;&lt;li data-block-key=&quot;2mk57&quot;&gt;Results viewable in any WebRTC-capable browser&lt;/li&gt;&lt;li data-block-key=&quot;3ebd3&quot;&gt;Full touch input and interactivity across multiple screens&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-33 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://www.qt.io/&quot; title=&quot;Logos_BuiltQt&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_BuiltQt&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_BuiltQt_dhgNqiu.original.png&quot; class=&quot;Logos_BuiltQt&quot; alt=&quot;Logos_BuiltQt&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;devicelab-for-embedded-hardware&quot; data-block-key=&quot;gkfs9&quot;&gt;DeviceLab for Embedded Hardware&lt;/h2&gt;&lt;h3 id=&quot;continuous-integration-system-on-real-devices&quot; data-block-key=&quot;xi51e&quot;&gt;Continuous Integration System on Real Devices&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;80r8p&quot;&gt;DeviceLab allows for testing Flutter applications on various embedded boards&lt;/li&gt;&lt;li data-block-key=&quot;99eam&quot;&gt;The Flutter developer experience on embedded is falling short at the moment&lt;/li&gt;&lt;li data-block-key=&quot;aj40a&quot;&gt;To improve the experience, it is necessary to start testing Flutter on embedded hardware&lt;/li&gt;&lt;li data-block-key=&quot;aqn1u&quot;&gt;A big improvement would be to integrate some of the most common embedded platforms into the official Flutter DeviceLab&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-50 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://flutter.dev/&quot; title=&quot;Logos_Flutter&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_Flutter&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_Flutter_3o7mIJr.original.png&quot; class=&quot;Logos_Flutter&quot; alt=&quot;Logos_Flutter&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-50 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                    &lt;a href=&quot;https://www.industrialflutter.com/&quot; title=&quot;Logos_IF&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                &lt;img id=&quot;Logos_IF&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_IF.original.png&quot; class=&quot;Logos_IF&quot; alt=&quot;Logos_IF&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;cxx-qt-safe-rust-bindings-for-qt&quot; data-block-key=&quot;10r9a&quot;&gt;CXX-Qt - Safe Rust Bindings for Qt&lt;/h2&gt;&lt;h3 id=&quot;integration-for-c++-and-rust-applications&quot; data-block-key=&quot;f6vjv&quot;&gt;Integration for C++ and Rust applications&lt;/h3&gt;&lt;p data-block-key=&quot;epkcs&quot;&gt;KDAB supports and maintains &lt;a href=&quot;https://github.com/KDAB/cxx-qt&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;CXX-Qt&lt;/a&gt;. A set of Rust crates for creating bidirectional Rust ⇄ C++ bindings with Qt. It can be used to integrate Rust into C++ applications via CMake, or to build Rust applications with Cargo.&lt;/p&gt;&lt;p data-block-key=&quot;2tdvt&quot;&gt;Watch our YouTube series &lt;a href=&quot;https://www.youtube.com/playlist?list=PL6CJYn40gN6jOg_cPqRfXMNriHknKy4VW&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;&quot;Mixing C++ and Rust&quot;&lt;/a&gt; to learn more.&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;3ame5&quot;&gt;Enables Rust and C++ ecosystems to be used in the same application&lt;/li&gt;&lt;li data-block-key=&quot;2g8vu&quot;&gt;Allows for idiomatic Rust and C++ code&lt;/li&gt;&lt;li data-block-key=&quot;8l2o3&quot;&gt;Integrates easily into existing applications&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-25 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://rust-lang.org/&quot; title=&quot;Logos_Rust&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_Rust&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_Rust.original.png&quot; class=&quot;Logos_Rust&quot; alt=&quot;Logos_Rust&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;developer-tools-for-qt-c++-and-linux&quot; data-block-key=&quot;vnr5d&quot;&gt;Developer Tools for Qt, C++, and Linux&lt;/h2&gt;&lt;h3 id=&quot;performance-optimization-tools&quot; data-block-key=&quot;28cdf&quot;&gt;Performance Optimization Tools&lt;/h3&gt;&lt;p data-block-key=&quot;ba833&quot;&gt;A selection of useful developer tools for debugging and profiling&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;cnj96&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/gammaray/&quot;&gt;GammaRay&lt;/a&gt;: High-level introspection tool for Qt applications&lt;/li&gt;&lt;li data-block-key=&quot;4jocq&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/kddockwidgets/&quot;&gt;KDDockWidgets&lt;/a&gt;: KDAB&apos;s Dock Widget Framework for Qt&lt;/li&gt;&lt;li data-block-key=&quot;1e4n&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/hotspot/&quot;&gt;Hotspot&lt;/a&gt;: The Linux perf GUI for performance analysis&lt;/li&gt;&lt;li data-block-key=&quot;dul2b&quot;&gt;&lt;a href=&quot;https://www.kdab.com/clazy-video/&quot;&gt;Clazy Static Code Analyzer&lt;/a&gt;: LLVM/Clang-based static analyzer for Qt&lt;/li&gt;&lt;li data-block-key=&quot;4qtfk&quot;&gt;&lt;a href=&quot;https://github.com/KDE/heaptrack&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Heaptrack&lt;/a&gt;: Heap memory profiler and analysis GUI for Linux&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;meet-kdab-in-hall-4-booth-302&quot; data-block-key=&quot;1thxu&quot;&gt;Meet KDAB in Hall 4 Booth 302&lt;/h2&gt;&lt;p data-block-key=&quot;935ua&quot;&gt;Visit our booth to see these demos live and talk directly with KDAB engineers about your embedded projects.&lt;/p&gt;&lt;p data-block-key=&quot;4k83v&quot;&gt;Want to meet during the show? Email us at info@kdab.com to arrange a meeting.&lt;/p&gt;&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;videos-from-previous-embedded-worlds&quot; data-block-key=&quot;orrqb&quot;&gt;Videos from Previous Embedded Worlds&lt;/h2&gt;&lt;p data-block-key=&quot;fftv9&quot;&gt;Are you curious what KDAB brought to previous editions of Embedded World? Take a look at this playlist:&lt;/p&gt;&lt;/div&gt;







&lt;div class=&quot;cookieconsent-optin-marketing overlay-embed-block&quot;&gt;
    &lt;div style=&quot;padding-bottom: 56.49999999999999%;&quot; class=&quot;responsive-object&quot;&gt;
    &lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/videoseries?list=PL6CJYn40gN6hdOVE4eSKnZ4vv7333xmDP&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;style&gt;
.overlay-embed-block .responsive-object {
    position: relative;
}

.overlay-embed-block .responsive-object iframe,
.overlay-embed-block .responsive-object object,
.overlay-embed-block .responsive-object embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
&lt;/style&gt;


&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/kdab-at-embedded-world-2026-nuremberg-germany/&quot;&gt;KDAB at Embedded World 2026, Nuremberg, Germany&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Editor Team</dc:creator></item><item><title>MSVC - Debugging the Static Initialization Order</title><link>https://www.kdab.com/msvc-debugging-the-static-initialization-order/</link><guid isPermaLink="true">https://www.kdab.com/msvc-debugging-the-static-initialization-order/</guid><description>&lt;p data-block-key=&quot;1yf9k&quot;&gt;A bug which is &lt;b&gt;experienced by&lt;/b&gt; and also &lt;b&gt;caused by&lt;/b&gt; code running before main(). How do you deal with that? This article explains the underlying mechanics of how static initialization works, and one way to debug it.&lt;/p&gt;</description><pubDate>Thu, 18 Dec 2025 07:48:00 GMT</pubDate><content:encoded>&lt;h1&gt;MSVC - Debugging the Static Initialization Order&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;4jay6&quot;&gt;Have you ever encountered a bug which is &lt;b&gt;&lt;i&gt;experienced by&lt;/i&gt;&lt;/b&gt; and also &lt;b&gt;&lt;i&gt;caused by&lt;/i&gt;&lt;/b&gt; code running before main() even starts? This can happen if you have a static variable or singleton of a class. Each constructor of such classes gets called in order. But what order?&lt;/p&gt;&lt;p data-block-key=&quot;bar93&quot;&gt;Turns out, this order is undefined by design. And this actually has a name:&lt;br/&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/siof.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;Static Initialization Order Fiasco&lt;/i&gt;&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;18v5q&quot;&gt;This mentions code depending on other code. I certainly don&apos;t recommend ever intentionally designing an application with such dependencies. But... it can still happen. That&apos;s when this knowledge is useful.&lt;/p&gt;&lt;h2 id=&quot;how-the-initialization-works&quot; data-block-key=&quot;ihewx&quot;&gt;How the initialization works&lt;/h2&gt;&lt;p data-block-key=&quot;ainif&quot;&gt;When the program compiles and links, a table of function pointers to all the static methods which need to be called to initialize the static variables is created.&lt;br/&gt;Then, the MainCRTStartup function loops over these pointers and calls them. Again, all this happens before &lt;code&gt;main()&lt;/code&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;daqg8&quot;&gt;With this background info, we can be more specific in formulating the problem:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;al1pv&quot;&gt;One of the constructors of a static variable leaves behind its side effects which leads to code in another constructor crashing.&lt;/li&gt;&lt;li data-block-key=&quot;ccv9b&quot;&gt;We can see the outcome where its side effects cause problems in subsequent constructors/static methods.&lt;ul&gt;&lt;li data-block-key=&quot;fuq7&quot;&gt;But we don&apos;t know how many constructors were called before &quot;ours&quot;.&lt;/li&gt;&lt;li data-block-key=&quot;5c1pk&quot;&gt;We don&apos;t know which of those are causing it.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li data-block-key=&quot;26dbg&quot;&gt;We need to know this to limit the scope.&lt;/li&gt;&lt;li data-block-key=&quot;atibb&quot;&gt;The error must be somewhere in there.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;what-the-underlying-code-looks-like&quot; data-block-key=&quot;t3jtp&quot;&gt;What the underlying code looks like&lt;/h2&gt;&lt;p data-block-key=&quot;dgel8&quot;&gt;Wouldn&apos;t it be great if we could examine the &quot;MainCRTStartup&quot;?&lt;/p&gt;&lt;p data-block-key=&quot;enqbc&quot;&gt;Microsoft actually supplies source code for this! It can be found in the file &lt;code&gt;exe_common.inl&lt;/code&gt; which in my case was found at &lt;code&gt;&quot;C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\crt\src\vcruntime\exe_common.inl&quot;&lt;/code&gt;&lt;/p&gt;&lt;p data-block-key=&quot;4u8eq&quot;&gt;The call to &lt;code&gt;_initterm&lt;/code&gt; performs this initialization (line 17):&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;bool has_cbool has_ctor = false;  
__try  
{  
    bool const is_nested = __scrt_acquire_startup_lock();  
  
    if (__scrt_current_native_startup_state == __scrt_native_startup_state::initializing)  
    {  
        __scrt_fastfail(FAST_FAIL_FATAL_APP_EXIT);  
    }  
    else if (__scrt_current_native_startup_state == __scrt_native_startup_state::uninitialized)  
    {  
        __scrt_current_native_startup_state = __scrt_native_startup_state::initializing;  
  
        if (_initterm_e(__xi_a, __xi_z) != 0)  
            return 255;  
  
        _initterm(__xc_a, __xc_z);  // &amp;lt;--- THIS LINE (256)!
  
        __scrt_current_native_startup_state = __scrt_native_startup_state::initialized;  
    }  
    else  
    {  
        has_cctor = true;  
    }  
  
    __scrt_release_startup_lock(is_nested);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;debugging-this-with-x64-debug&quot; data-block-key=&quot;35dgt&quot;&gt;Debugging this with &lt;a href=&quot;https://x64dbg.com/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;x64-debug&lt;/a&gt;&lt;/h2&gt;&lt;p data-block-key=&quot;bha98&quot;&gt;Depending on the debugger, this might be out of scope for your IDE. This was the case for me.&lt;/p&gt;&lt;h3 id=&quot;prerequisites&quot; data-block-key=&quot;1xmid&quot;&gt;Prerequisites&lt;/h3&gt;&lt;p data-block-key=&quot;dbeg0&quot;&gt;It&apos;s assumed you can either use a regular debug build or a release build with generated PDB file (&lt;code&gt;/Zi&lt;/code&gt; flag to generate separate PDB for MSVC compiler).&lt;/p&gt;&lt;p data-block-key=&quot;2n2b7&quot;&gt;Ensure entry breakpoint is set in the options dialog:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113016&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Pasted_image_20250505113016.original.png&quot; class=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113016&quot; alt=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113016&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;lw7jy&quot;&gt;This automatic breakpoint will pause the debugging at the program entry point - not main() but the actual entry point.&lt;/p&gt;&lt;h3 id=&quot;stepping-into-the-program&quot; data-block-key=&quot;dbxs0&quot;&gt;Stepping into the program&lt;/h3&gt;&lt;p data-block-key=&quot;6ak7a&quot;&gt;There is a lot to look at in this screenshot. The program is called &lt;code&gt;gltf_render_pbr&lt;/code&gt;. Use the &lt;b&gt;&lt;i&gt;step-into&lt;/i&gt;&lt;/b&gt; button in the debugger until you reach the correct &quot;file&quot; - it will tell you on the right hand side. Look at the very right for &lt;code&gt;exe_common.inl&lt;/code&gt;&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113502&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Pasted_image_20250505113502.original.png&quot; class=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113502&quot; alt=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113502&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;lw7jy&quot;&gt;Now you can find the correct line for the breakpoint. It is marked in red here. Also notice the &lt;code&gt;__xc_z&lt;/code&gt; and &lt;code&gt;__xc_a&lt;/code&gt;, those are the start and end pointers of the table where the static initializer function pointers are stored. Note the little red dot to the left of the red highlighted address? That means I have a breakpoint set on that instruction. The &lt;code&gt;call &amp;lt;gltf_render_pbr._initterm&amp;gt;&lt;/code&gt; instruction. This is the one jumping into the actual performing code inside &lt;code&gt;ucrtbased.dll&lt;/code&gt;.&lt;/p&gt;&lt;h3 id=&quot;ucrtbased.dll-loop&quot; data-block-key=&quot;8rf9f&quot;&gt;ucrtbased.dll loop&lt;/h3&gt;&lt;p data-block-key=&quot;dn0pc&quot;&gt;When you step into that, you will end up here:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113859&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Pasted_image_20250505113859.original.png&quot; class=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113859&quot; alt=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113859&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;lw7jy&quot;&gt;This is the loop which calls each initializer in the list.&lt;/p&gt;&lt;p data-block-key=&quot;m48k&quot;&gt;The actual call into each initialization method is: &lt;code&gt;call qword ptr ds:[7FFCD4B6BBA0]&lt;/code&gt;.&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;ciiim&quot;&gt;Set a breakpoint there like I&apos;ve done in the screenshot above.&lt;/li&gt;&lt;li data-block-key=&quot;4vebv&quot;&gt;Now, from there, &lt;b&gt;&lt;i&gt;step into&lt;/i&gt;&lt;/b&gt; 2 times more to reach the actual code.&lt;/li&gt;&lt;li data-block-key=&quot;9g18g&quot;&gt;When you&apos;ve noted where you ended up, just press &lt;b&gt;run&lt;/b&gt; and you should get back to the breakpoint. It&apos;s inside the loop after all.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;rpy7t&quot;&gt;Note that the first static method the &quot;pre_cpp_initialization&quot; step in the CRT code, &lt;code&gt;exe_common.inl:216&lt;/code&gt;&lt;br/&gt; It initializes exception handlers and other things.&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;q02c7&quot;&gt;The next call should be into actual C++ initializers. If you have debug symbols, you should be able to see where you end up. In the example program I used - &lt;code&gt;fmt&lt;/code&gt; had a static method, and then the next after that was my test code.&lt;/p&gt;&lt;h3 id=&quot;when-debugging-the-program-next-time&quot; data-block-key=&quot;l7vmx&quot;&gt;When debugging the program next time&lt;/h3&gt;&lt;p data-block-key=&quot;7di64&quot;&gt;When you restart the program in the debugger, &lt;b&gt;each DLL&lt;/b&gt; will also have its own CRT startup sequence. Thus:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;2m6l4&quot;&gt;disable the breakpoint inside the loop in ucrtbased.dll&lt;/li&gt;&lt;li data-block-key=&quot;dudhv&quot;&gt;run until the breakpoint for the &lt;code&gt;_initterm&lt;/code&gt; call&lt;/li&gt;&lt;li data-block-key=&quot;6peed&quot;&gt;re-enable the breakpoint inside the loop in ucrtbased.dll&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/msvc-debugging-the-static-initialization-order/&quot;&gt;MSVC - Debugging the Static Initialization Order&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>c++</category><category>desktop</category><category>windows</category></item><item><title>Static Assertions in Rust</title><link>https://www.kdab.com/static-assertions-in-rust/</link><guid isPermaLink="true">https://www.kdab.com/static-assertions-in-rust/</guid><description>&lt;p data-block-key=&quot;o00k7&quot;&gt;Rust doesn’t include a built-in equivalent to C++’s static_assert, but you can achieve similar compile-time checks with a simple macro. This allows you to enforce conditions during compilation without external dependencies. While the Rust standard library has opted not to include such functionality, it&apos;s easy to implement and integrate directly into your own projects.&lt;/p&gt;</description><pubDate>Thu, 20 Nov 2025 07:58:00 GMT</pubDate><content:encoded>&lt;h1&gt;Static Assertions in Rust&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;In C++, we have a useful way to ensure certain conditions are met during compilation. This is called &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/static_assert.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;static_assert&lt;/a&gt;. Here is an oversimplified example, which should always pass:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;constexpr int A = 6;

static_assert(A == 6);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;In Rust it&apos;s not obvious that we have an equivalent for &lt;code&gt;static_assert&lt;/code&gt; out of the box. Of course, we have the &lt;a href=&quot;https://doc.rust-lang.org/std/macro.assert.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;assert! macro&lt;/a&gt; but there&apos;s nothing built-in like a &lt;code&gt;static_assert!&lt;/code&gt; or the more fitting &lt;code&gt;const_assert!&lt;/code&gt; to use. However, with modern Rust, it’s easy to make an equivalent to use in your projects with a small macro.&lt;/p&gt;&lt;p data-block-key=&quot;3h5na&quot;&gt;The macro code is short and sweet, so let&apos;s begin by showing it first:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;macro_rules! const_assert {
    ($x:expr) =&amp;gt; {
        const _: () = ::core::assert!($x);
    };
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;If you haven&apos;t come across &lt;code&gt;const&lt;/code&gt; in Rust, it has a different meaning than in C++. You can read more &lt;a href=&quot;https://doc.rust-lang.org/std/keyword.const.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;about it here&lt;/a&gt; but the main difference is that it usually means &quot;compile-time&quot;, while in C++ it means &quot;immutable&quot; or &quot;constant&quot;. If the Rust compiler can&apos;t evaluate it at compile-time, it throws an error.&lt;/p&gt;&lt;p data-block-key=&quot;5dalv&quot;&gt;Now going back to the &lt;code&gt;macro_rules!&lt;/code&gt; part, let me explain this super simple example. First, we define a name for the macro - in this case &lt;code&gt;const_assert&lt;/code&gt;:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;macro_rules! const_assert&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;Then we want to define how the arguments are matched and parsed. These are called designators, and they are written in the form of &lt;code&gt;$name:type&lt;/code&gt;. So in our case, we are defining &lt;code&gt;$x&lt;/code&gt; with a type of &lt;code&gt;expr&lt;/code&gt; (short for expression.)&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;($x:expr) =&amp;gt; {&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;Now that we have an expression, we can substitute it in new code. For our case that&apos;s putting it in an &lt;code&gt;assert!&lt;/code&gt; but in a &lt;code&gt;const&lt;/code&gt; context:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;const _: () = ::core::assert!($x);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;Macros are a huge topic on their own, and our example here is on the easier side. You can read more about how &lt;code&gt;macro_rules!&lt;/code&gt; can be used &lt;a href=&quot;https://doc.rust-lang.org/rust-by-example/macros.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; if you&apos;re curious. If you want to test your skills, try modifying the macro to accept other forms of &lt;code&gt;assert!&lt;/code&gt;, e.g. to pass a custom error message.&lt;/p&gt;&lt;p data-block-key=&quot;98udq&quot;&gt;Let&apos;s move back to &lt;code&gt;const_assert!&lt;/code&gt;, here&apos;s the above example but written in Rust:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;const A: i32 = 6;

const_assert!(A == 6);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;And it&apos;s roughly equivalent to writing this manually:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;const A: i32 = 6;

const _: () = assert!(A == 6);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;In my opinion, though, the intent isn&apos;t as clear in the non-macro version. The nice thing about the macro - and the main draw - is that it looks like an &lt;code&gt;assert!&lt;/code&gt; which is an existing language construct that you would already be familiar reading.&lt;/p&gt;&lt;p data-block-key=&quot;ev9gk&quot;&gt;And similar to &lt;code&gt;static_assert&lt;/code&gt; in C++, the macro can be put in the global scope and also in functions:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;const A: i32 = 6;

const B: i32 = 5;

const_assert!(B == 6);

fn main() {
    const_assert!(A == 6);

    println!(&amp;quot;{A}&amp;quot;);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;I didn’t create this macro, I stumbled across it while researching static assertions to use in &lt;a href=&quot;https://github.com/KDAB/CXX-Qt&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;CXX-Qt&lt;/a&gt;. I was initially going to pick from one of the many choices of static assertion crates, until I looked at their source code and found a lot of them are identical to the macro I showed above. Since &lt;code&gt;macro_rules!&lt;/code&gt; are so easy to integrate, it made sense to vendor it instead of adding another dependency.&lt;/p&gt;&lt;p data-block-key=&quot;8ol30&quot;&gt;There was an issue brought forward to the Rust Library team to add something akin to C++&apos;s &lt;code&gt;static_assert&lt;/code&gt; into &lt;a href=&quot;https://github.com/rust-lang/libs-team/issues/325&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;the standard library&lt;/a&gt;. The thread goes over some of the limitations with the method shown here as well. Yet &lt;a href=&quot;https://github.com/rust-lang/libs-team/issues/325#issuecomment-2807186979&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;they ultimately decided&lt;/a&gt; that having an equivalent in the standard library isn&apos;t something they want. I&apos;m not sure if I agree with that decision, but, fortunately, it&apos;s easy to add your own.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/static-assertions-in-rust/&quot;&gt;Static Assertions in Rust&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>rust</category></item><item><title>Understanding Type-Based Alias Analysis in C and C++</title><link>https://www.kdab.com/understanding-type-based-alias-analysis-in-c-and-cpp/</link><guid isPermaLink="true">https://www.kdab.com/understanding-type-based-alias-analysis-in-c-and-cpp/</guid><description>&lt;p data-block-key=&quot;hon5z&quot;&gt;Type systems do more than just catch errors - they guide compiler optimizations too. This post explores type-based alias analysis in C and C++, showing how aliasing affects performance, why undefined behavior matters, and how the restrict keyword helps unlock faster code.&lt;/p&gt;</description><pubDate>Wed, 22 Oct 2025 10:31:00 GMT</pubDate><content:encoded>&lt;h1&gt;Understanding Type-Based Alias Analysis in C and C++&lt;/h1&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;what-are-type-systems&quot; data-block-key=&quot;e1mbz&quot;&gt;What are Type Systems?&lt;/h2&gt;&lt;p data-block-key=&quot;2d2rr&quot;&gt;Type system in statically typed language empowers compilers to identify and reject invalid programs during the type checking phase. Type information associated with different elements of the program (e.g. functions, variables) helps the compiler to detect the state of the program without actually executing the program. While programming language types are frequently employed to detect specific errors during compilation, what is interesting and important is that they serve other purposes as well.&lt;/p&gt;&lt;h2 id=&quot;let&amp;#x27;s-talk-about-type-based-alias-analysis&quot; data-block-key=&quot;sf2dk&quot;&gt;Let’s Talk about Type-based Alias Analysis&lt;/h2&gt;&lt;p data-block-key=&quot;2c8p8&quot;&gt;Type-based alias analysis is a technique that determines whether two or more pointers or references in a program can potentially point to the same memory address (alias each other, in other words). This analysis mainly relies on the concept of compatible types.&lt;/p&gt;&lt;p data-block-key=&quot;dbjao&quot;&gt;But what exactly are compatible types?&lt;/p&gt;&lt;p data-block-key=&quot;779ph&quot;&gt;So, aliasing typically occurs between compatible data types. To clarify, data types are deemed compatible when they differ only in attributes like being signed, unsigned, const, or volatile. For instance, both &quot;char&quot; and &quot;unsigned char&quot; are compatible with any other type.&lt;/p&gt;&lt;p data-block-key=&quot;8kkpg&quot;&gt;Let’s look at a simple example to understand better:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;void modifyValues(int *a, short *b) {
  *a = 42;
  *b = 3;
  *a += 5;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;Assuming the function call is &lt;b&gt;modifyValues(&amp;amp;n, (short*)&amp;amp;n)&lt;/b&gt; here, &lt;b&gt;n&lt;/b&gt; might be an integer type.&lt;/p&gt;&lt;p data-block-key=&quot;710ne&quot;&gt;What would be the resulting value of n?&lt;/p&gt;&lt;p data-block-key=&quot;cc1nn&quot;&gt;It depends on the optimization level. Let’s look at the assembly in the case of no optimization level (O0) and its being compiled with clang.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;mov rax, qword ptr [rbp - 8]
mov dword ptr [rax], 42  ; *a = 42

mov rax, qword ptr [rbp - 16]
mov word ptr [rax], 3    ; *b = 3

mov rax, qword ptr [rbp - 8]
mov ecx, dword ptr [rax]
add ecx, 5               ; *a += 5;&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;This is pretty much standard, similar to what we wrote in high-level code - basically a one-to-one mapping. Looking at the assembly, it is clear that there is aliasing, a and b pointing to the exact same location. Hence, the final value for &lt;b&gt;n&lt;/b&gt; would be 8 in this case.&lt;/p&gt;&lt;p data-block-key=&quot;chfub&quot;&gt;Now, let’s compile the program using an optimization level -O2 ,&lt;/p&gt;&lt;p data-block-key=&quot;3c34f&quot;&gt;Take a look at this big assembly:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;mov word ptr [rsi], 3
mov dword ptr [rdi], 47&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;




&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;void modifyValues(int *a, short *b) {
  *b = 3;
  *a = 47;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;In this case, the final value of n would be 47.&lt;/p&gt;&lt;p data-block-key=&quot;ddqj3&quot;&gt;Though, is that program right in this case? Obviously, it is not. There is undefined behavior, which is visible through how different optimization levels have different results.&lt;/p&gt;&lt;p data-block-key=&quot;3a1a7&quot;&gt;Why is that?&lt;/p&gt;&lt;p data-block-key=&quot;98o38&quot;&gt;In accordance with the C and C++ standards, when you try to access an object of one type (e.g., int) using an lvalue expression of a different type (e.g., short in a function argument), and these types are not considered compatible (except for specific exceptions outlined in the standards), it leads to undefined behavior. This means that the program&apos;s behavior cannot be predicted or relied upon, and it may produce unexpected results.&lt;/p&gt;&lt;p data-block-key=&quot;3lt8j&quot;&gt;Personally speaking, I really like when undefined behavior teaches much more about programming than the defined behavior. :)&lt;/p&gt;&lt;h2 id=&quot;tbaa-in-action:&quot; data-block-key=&quot;keqy1&quot;&gt;TBAA in Action:&lt;/h2&gt;&lt;p data-block-key=&quot;5s3mo&quot;&gt;Consider the following example:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;void Foo(float *v, int *n) {
  for (int i = 0; i &amp;lt; *n; i++)
    v[i] += 1.0f;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;In this case, the compiler and TBAA ensure that the types are not compatible and memory lookup for *n can be optimized by performing it just once. The resulting value can be stored in a register, which is then accessed in each iteration of the loop. This optimization helps reduce memory access overhead and can lead to improved performance.&lt;/p&gt;&lt;p data-block-key=&quot;450c&quot;&gt;Now, consider this example:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;void Foo(float v[], float *c, int n) {
  for (int i = 0; i &amp;lt; n; i++)
    v[i] = *c + 1.0f;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;In the provided example, the types of &lt;b&gt;v&lt;/b&gt; and &lt;b&gt;c&lt;/b&gt; are compatible, which leads the compiler to assume they may alias, meaning they could refer to the same memory location. Consequently, the compiler takes measures to ensure that fetching the value of &lt;b&gt;*c&lt;/b&gt; within the loop will indeed be performed in each iteration. This behavior is implemented to guarantee that the value pointed to by &lt;b&gt;c&lt;/b&gt; is fetched afresh in every iteration of the loop. However, it&apos;s important to note that this meticulous handling, while beneficial for correctness, can potentially impact performance.&lt;/p&gt;&lt;h2 id=&quot;for-more-details-let&amp;#x27;s-look-at-their-assembly&quot; data-block-key=&quot;zqb1d&quot;&gt;For More Details Let&apos;s Look at their Assembly&lt;/h2&gt;&lt;p data-block-key=&quot;qg92&quot;&gt;&lt;b&gt;First Version (Non-compatible types):&lt;/b&gt;&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;Foo(float*, int*):
    movsx rax, DWORD PTR [rsi]
    test eax, eax
    jle .L1
    movss xmm1, DWORD PTR .LC0[rip]
    lea rax, [rdi+rax*4]
.L3:
    movss xmm0, DWORD PTR [rdi]
    add rdi, 4
    addss xmm0, xmm1
    movss DWORD PTR [rdi-4], xmm0
    cmp rdi, rax
    jne .L3
.L1:
    ret&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;&lt;b&gt;Second Version (Compatible types):&lt;/b&gt;&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;Foo(float*, float*, int):
    test edx, edx
    jle .L1
    movsx rdx, edx
    movss xmm1, DWORD PTR .LC0[rip]
    lea rax, [rdi+rdx*4]
.L3:
    movss xmm0, DWORD PTR [rsi]
    add rdi, 4
    addss xmm0, xmm1
    movss DWORD PTR [rdi-4], xmm0
    cmp rdi, rax
    jne .L3&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;In the first version &lt;b&gt;(Foo(float*, int*))&lt;/b&gt;, the loop counter n is passed as a pointer to an integer &lt;b&gt;(int*)&lt;/b&gt;. The code loads this integer value &lt;b&gt;(*n)&lt;/b&gt; into a register &lt;b&gt;(rax)&lt;/b&gt; before entering the loop, and then uses this register for loop control.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;movsx rax, DWORD PTR [rsi]&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;This means that the loop counter is loaded from memory once at the beginning of the loop, and the register value is used throughout the loop iterations.&lt;/p&gt;&lt;p data-block-key=&quot;ftm48&quot;&gt;In the second version in each iteration of the loop, &lt;b&gt;*c&lt;/b&gt; is loaded into xmm0.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;movss xmm0, DWORD PTR [rsi]&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;This behavior ensures that the value pointed to by &lt;b&gt;*c&lt;/b&gt; is consistent throughout the loop iterations.&lt;/p&gt;&lt;p data-block-key=&quot;bravk&quot;&gt;Have you noticed how type-based alias analysis benefits compilers to take optimizations action?&lt;/p&gt;&lt;p data-block-key=&quot;7fuso&quot;&gt;But the question remains:&lt;br/&gt;What is an explicit fix for this, or hint to the compiler that there is no chance of aliasing even in the case of compatible types?&lt;/p&gt;&lt;p data-block-key=&quot;7045t&quot;&gt;In C, the restrict keyword comes to the rescue when you want to explicitly inform the compiler that there is no chance of aliasing between pointers.&lt;/p&gt;&lt;p data-block-key=&quot;e5qpv&quot;&gt;Consider this example:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;void Foo(float* restrict v, float* c, int n) {
  for (int i = 0; i &amp;lt; n; i++)
    v[i] = *c + 1.0f;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;In practice, you may need to declare both pointers as restrict if you can guarantee that they don&apos;t alias each other.&lt;/p&gt;&lt;h3 id=&quot;let&amp;#x27;s-look-at-the-assembly-for-the-above-code:&quot; data-block-key=&quot;qc8uy&quot;&gt;Let&apos;s Look at the Assembly for the Above Code:&lt;/h3&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;Foo:
test edx, edx
jle .L1
movsx rdx, edx
movss xmm0, DWORD PTR .LC0[rip]
lea rax, [rdi+rdx*4]
and edx, 1
je .L3
movss DWORD PTR [rdi], xmm0
add rdi, 4
and edx, 1
je .L11
.L3:
movss DWORD PTR [rdi], xmm0
add rdi, 8
movss DWORD PTR [rdi-4], xmm0
cmp rdi, rax
je .L11&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;See how it impacted the performance:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;movss xmm0, DWORD PTR .LC0[rip]  ; Load 1.0f into xmm0
addss xmm0, DWORD PTR [rsi]      ; Add *c to xmm0&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;The &lt;b&gt;movss&lt;/b&gt; instruction loads the constant 1.0f into &lt;b&gt;xmm0&lt;/b&gt;, and then &lt;b&gt;addss&lt;/b&gt; adds the value pointed to by &lt;b&gt;&lt;i&gt;c&lt;/i&gt;&lt;/b&gt;&lt;i&gt; to&lt;/i&gt; &lt;b&gt;&lt;i&gt;xmm0&lt;/i&gt;&lt;/b&gt;&lt;i&gt;.&lt;/i&gt; Importantly&lt;i&gt;,&lt;/i&gt; &lt;b&gt;c&lt;/b&gt; is loaded into &lt;b&gt;xmm0&lt;/b&gt; only once outside the loop and re-used in the loop. Using the &lt;b&gt;restrict&lt;/b&gt; keyword, you provide the compiler with the assurance that the memory regions accessed through the pointers &lt;b&gt;v&lt;/b&gt; and &lt;b&gt;c&lt;/b&gt; do not overlap. The compiler can then optimize the code more aggressively for performance.&lt;/p&gt;&lt;p data-block-key=&quot;4ljbk&quot;&gt;However, a word of caution: you must be very careful when using restrict, as the compiler won&apos;t warn you about its incorrect use.&lt;/p&gt;&lt;p data-block-key=&quot;10qv5&quot;&gt;Interestingly, the restrict keyword is not a part of C++. Why is that?&lt;/p&gt;&lt;p data-block-key=&quot;9sgmd&quot;&gt;The history behind this decision is quite intriguing. When reviewing C99 features for inclusion in C++, there was consideration of adding &lt;a href=&quot;https://www.geeksforgeeks.org/restrict-keyword-c/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/a&gt;. However, no paper proposal was made at the time. Hence, it didn&apos;t make its way into C++.&lt;/p&gt;&lt;p data-block-key=&quot;ckhli&quot;&gt;&lt;b&gt;restrict&lt;/b&gt; was originally designed for fine-grain aliasing in C but may not be well-suited for the type-based aliasing that is more common in C++. In C++, pointers are less prevalent in class abstractions and restrict may not align well with the C++ language design.&lt;/p&gt;&lt;p data-block-key=&quot;ci7p3&quot;&gt;In summary, the restrict keyword in C and type-based alias analysis are tools that help compilers generate efficient and optimized code while maintaining program correctness and adherence to language standards.&lt;/p&gt;&lt;p data-block-key=&quot;1i6ok&quot;&gt;Thank you for reading!&lt;/p&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/understanding-type-based-alias-analysis-in-c-and-cpp/&quot;&gt;Understanding Type-Based Alias Analysis in C and C++&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>c++</category><category>performance</category><category>tools</category></item><item><title>KDAB at Embedded World NA 2025</title><link>https://www.kdab.com/kdab-at-embedded-world-na-2025/</link><guid isPermaLink="true">https://www.kdab.com/kdab-at-embedded-world-na-2025/</guid><description>&lt;p data-block-key=&quot;pvuv9&quot;&gt;KDAB will be exhibiting at &lt;b&gt;Embedded World North America&lt;/b&gt; from &lt;b&gt;November 4th through 6th, 2025&lt;/b&gt;, in Anaheim, California.&lt;/p&gt;</description><pubDate>Tue, 21 Oct 2025 06:51:00 GMT</pubDate><content:encoded>&lt;h1&gt;KDAB at Embedded World NA 2025&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;0n636&quot;&gt;KDAB will be exhibiting at &lt;a href=&quot;https://embedded-world-na.com/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;Embedded World North America&lt;/b&gt;&lt;/a&gt; from &lt;b&gt;November 4th through 6th, 2025&lt;/b&gt;, in Anaheim, California.&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;Event Details:&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;rwxf7&quot;&gt;📍 Anaheim, California&lt;br/&gt;📅 November 4–6, 2025&lt;br/&gt;📍 KDAB Booth: 5039&lt;/p&gt;&lt;p data-block-key=&quot;bj43n&quot;&gt;Get your tickets &lt;a href=&quot;https://www.prereg.net/2025/ewna/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;explore-kdab-demos&quot; data-block-key=&quot;pbqxu&quot;&gt;&lt;b&gt;Explore KDAB Demos&lt;/b&gt;&lt;/h2&gt;&lt;/div&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;live-3d-ui-for-autonomous-public-transport&quot; data-block-key=&quot;32a80&quot;&gt;Live 3D UI for Autonomous Public Transport&lt;/h3&gt;&lt;p data-block-key=&quot;124qn&quot;&gt;&lt;i&gt;The UI displays the autonomous driver&apos;s real-time awareness and planned actions to the vehicle users.&lt;/i&gt;&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;ed3pm&quot;&gt;Autonomous bus driven by &lt;a href=&quot;https://www.motor-ai.com/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Motor AI&lt;/a&gt; infrastructure&lt;/li&gt;&lt;li data-block-key=&quot;9cl3j&quot;&gt;Interactive 3D dashboard powered by Serenity&lt;/li&gt;&lt;li data-block-key=&quot;343s4&quot;&gt;Real-time data streamed via MQTT&lt;/li&gt;&lt;li data-block-key=&quot;dsb87&quot;&gt;Touch interface built with &lt;a href=&quot;https://slint.dev/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Slint&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;qt-gstreamer-multi-display&quot; data-block-key=&quot;eah4p&quot;&gt;Qt GStreamer Multi-Display&lt;/h3&gt;&lt;p data-block-key=&quot;khdb&quot;&gt;&lt;i&gt;Stream Qt applications to Multiple Browser Instances&lt;/i&gt;&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;6d3fj&quot;&gt;Standard Qt/QML Application on an Intel Atom-based CPU&lt;/li&gt;&lt;li data-block-key=&quot;9gofm&quot;&gt;Complex GStreamer pipeline to transform into a WebRTC stream&lt;/li&gt;&lt;li data-block-key=&quot;cfjfb&quot;&gt;Results viewable in any WebRTC-capable browser&lt;/li&gt;&lt;li data-block-key=&quot;kn8n&quot;&gt;Full touch input and interactivity across multiple screens&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;medical-tool-for-interventional-cardiac-imaging&quot; data-block-key=&quot;piitf&quot;&gt;Medical tool for interventional cardiac imaging&lt;/h3&gt;&lt;p data-block-key=&quot;6tjf0&quot;&gt;&lt;a href=&quot;https://www.kdab.com/why-kdab/proven-excellence/luma-vision/&quot;&gt;&lt;i&gt;LUMA Vision and KDAB&lt;/i&gt;&lt;/a&gt;&lt;i&gt; developed a fully software-defined, end-to-end imaging system that could adapt to market and clinical needs.&lt;/i&gt;&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;52lk&quot;&gt;Uses Qt3D/Vulkan for visualisation of ultrasound data&lt;/li&gt;&lt;li data-block-key=&quot;a5a29&quot;&gt;Uses QML for 2D user interface&lt;/li&gt;&lt;li data-block-key=&quot;22mt&quot;&gt;CUDA-based 3D data processing&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;performance-optimization-tools&quot; data-block-key=&quot;sg5y1&quot;&gt;Performance optimization tools&lt;/h3&gt;&lt;p data-block-key=&quot;6nnab&quot;&gt;&lt;i&gt;For developers using Qt, C++, and Linux&lt;/i&gt;&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;bf31v&quot;&gt;&lt;a href=&quot;https://www.kdab.com/gammaray-3-3-released/&quot;&gt;GammaRay&lt;/a&gt;: High-level introspection tool for Qt applications&lt;/li&gt;&lt;li data-block-key=&quot;3l1u4&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/hotspot/&quot;&gt;Hotspot&lt;/a&gt;: The Linux perf GUI for performance analysis&lt;/li&gt;&lt;li data-block-key=&quot;13bot&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/kddockwidgets/&quot;&gt;KDDockWidgets&lt;/a&gt;: KDAB&apos;s Dock Widget Framework for Qt&lt;/li&gt;&lt;li data-block-key=&quot;brjin&quot;&gt;&lt;a href=&quot;https://www.kdab.com/clazy-results-visualizer-qt/&quot;&gt;Clazy&lt;/a&gt; Static Code Analyzer: LLVM/Clang-based static analyzer for Qt&lt;/li&gt;&lt;li data-block-key=&quot;cjqhm&quot;&gt;&lt;a href=&quot;https://www.kdab.com/heaptrack-demo-video/&quot;&gt;Heaptrack&lt;/a&gt;: Heap memory profiler and analysis GUI for Linux&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;meet-kdab-engineers&quot; data-block-key=&quot;1t3na&quot;&gt;&lt;b&gt;Meet KDAB Engineers&lt;/b&gt;&lt;/h3&gt;&lt;p data-block-key=&quot;a2tcv&quot;&gt;Let&apos;s discuss your specific &lt;b&gt;C++, Qt, Rust, and 3D development challenges.&lt;/b&gt; Visit KDAB in &lt;b&gt;booth 5039.&lt;/b&gt;&lt;/p&gt;&lt;p data-block-key=&quot;a31sr&quot;&gt;We look forward to connecting with you in Anaheim!&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://embedded-world-na.com/&quot; title=&quot;Embedded World NA&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Embedded World NA&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/embedded-world-north-america-logo.original.png&quot; class=&quot;Embedded World NA&quot; alt=&quot;Embedded World NA&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/kdab-at-embedded-world-na-2025/&quot;&gt;KDAB at Embedded World NA 2025&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Editor Team</dc:creator></item><item><title>GammaRay 3.3 Released</title><link>https://www.kdab.com/gammaray-3-3-released/</link><guid isPermaLink="true">https://www.kdab.com/gammaray-3-3-released/</guid><description>&lt;p data-block-key=&quot;8qq42&quot;&gt;GammaRay 3.3 introduces several updates aimed at maintaining compatibility with current Qt versions and improving stability across platforms.&lt;/p&gt;</description><pubDate>Mon, 20 Oct 2025 13:19:00 GMT</pubDate><content:encoded>&lt;h1&gt;GammaRay 3.3 Released&lt;/h1&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;9o0v3&quot;&gt;&lt;a href=&quot;https://github.com/KDAB/GammaRay/releases/tag/v3.3.0&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;GammaRay 3.3&lt;/a&gt; is now available.&lt;/p&gt;&lt;p data-block-key=&quot;f07t3&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/gammaray/&quot;&gt;GammaRay&lt;/a&gt; is a tool for developers working with the Qt framework, offering deep inspection capabilities that help you analyze, debug, and understand your applications at runtime. It provides insight into the behavior and state of Qt objects while the application is running, allowing for efficient troubleshooting, performance tuning, and exploration of complex UI or logic issues.&lt;/p&gt;&lt;h2 id=&quot;what&amp;#x27;s-new-in-gammaray-3.3&quot; data-block-key=&quot;wuko4&quot;&gt;What’s new in GammaRay 3.3&lt;/h2&gt;&lt;p data-block-key=&quot;e6097&quot;&gt;&lt;a href=&quot;https://github.com/KDAB/GammaRay/releases/tag/v3.3.0&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Version 3.3&lt;/a&gt; introduces several updates aimed at maintaining compatibility with current Qt versions and improving stability across platforms.&lt;/p&gt;&lt;p data-block-key=&quot;bsbur&quot;&gt;GammaRay has &lt;b&gt;dropped support for Qt 5&lt;/b&gt;, with the &lt;b&gt;minimum supported version now set to Qt 6.5&lt;/b&gt;. For developers who still rely on Qt 5, the 3.2 branch will continue to receive maintenance releases where necessary, including critical bug fixes and backports. This transition allows GammaRay to focus on modern Qt capabilities and simplifies ongoing development.&lt;/p&gt;&lt;p data-block-key=&quot;38ipk&quot;&gt;On Windows, &lt;b&gt;support for LLVM MinGW&lt;/b&gt; has been added, expanding the range of supported toolchains. A long-standing issue where the &lt;b&gt;GammaRay user interface&lt;/b&gt; would occasionally fail to appear on Windows has also been resolved.&lt;/p&gt;&lt;p data-block-key=&quot;e1gtn&quot;&gt;Additional improvements include updating the &lt;b&gt;LZ4 compression library to version 1.10.0&lt;/b&gt; and fixing build compatibility with &lt;b&gt;Qt 6.10&lt;/b&gt;, ensuring GammaRay continues to integrate smoothly with the latest Qt releases.&lt;/p&gt;&lt;p data-block-key=&quot;b025b&quot;&gt;You can find the full list of changes and downloads for this release on &lt;a href=&quot;https://github.com/KDAB/GammaRay/releases/tag/v3.3.0&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;6omod&quot;&gt;We look forward to feedback from users as they integrate GammaRay 3.3 into their workflows and encourage those still on older Qt versions to follow the 3.2 branch for continued support.&lt;/p&gt;&lt;h3 id=&quot;videos&quot; anchor=&quot;videos&quot; data-block-key=&quot;hqe6m&quot;&gt;Videos about GammaRay&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;8boj3&quot;&gt;GammaRay Tutorials: &lt;a href=&quot;https://www.youtube.com/playlist?list=PL6CJYn40gN6itybeSJb5FvRWOxVW5PCUX&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/playlist?list=PL6CJYn40gN6itybeSJb5FvRWOxVW5PCUX&lt;/a&gt;&lt;/li&gt;&lt;li data-block-key=&quot;dfeau&quot;&gt;GammaRay Tutorials for Qt Widgets Applications: &lt;a href=&quot;https://www.youtube.com/playlist?list=PL6CJYn40gN6izGNDIH06YXf0UzR_1BVhn&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/playlist?list=PL6CJYn40gN6izGNDIH06YXf0UzR_1BVhn&lt;/a&gt;&lt;/li&gt;&lt;li data-block-key=&quot;2pjq7&quot;&gt;More info on GammaRay: &lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/gammaray/&quot;&gt;https://www.kdab.com/software-technologies/developer-tools/gammaray/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/gammaray-3-3-released/&quot;&gt;GammaRay 3.3 Released&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Editor Team</dc:creator><category>tools</category></item><item><title>CI/CD Simplified: Comparing Buildbot, Jenkins, and GitHub Actions</title><link>https://www.kdab.com/cicd-simplified-comparing-buildbot-jenkins-and-github-actions/</link><guid isPermaLink="true">https://www.kdab.com/cicd-simplified-comparing-buildbot-jenkins-and-github-actions/</guid><description>&lt;p data-block-key=&quot;bfmwn&quot;&gt;Choosing the right CI/CD tool can make or break your development workflow. In this post, KDAB’s Jan Marker compares Buildbot, Jenkins, and GitHub Actions - exploring their strengths, trade-offs, and ideal use cases. You’ll also learn about helper tools like CMake Presets and pre-commit that can make your CI setup smoother and more efficient.&lt;/p&gt;</description><pubDate>Wed, 15 Oct 2025 07:24:59 GMT</pubDate><content:encoded>&lt;h1&gt;CI/CD Simplified: Comparing Buildbot, Jenkins, and GitHub Actions&lt;/h1&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;n41fu&quot;&gt;If you’re setting up a CI/CD pipeline, choosing the right tool is a big decision – a good CI system can save time, catch bugs early, and make deployments less stressful. But with so many options out there, figuring out what works best for your team can be overwhelming. In this post, I’ll break down three of the most popular CI/CD tools – &lt;b&gt;Buildbot&lt;/b&gt;, &lt;b&gt;Jenkins&lt;/b&gt;, and &lt;b&gt;GitHub Actions (GHA)&lt;/b&gt; – and share some tips on making them work for you. I’ll also talk about a couple of helper tools that can make your CI workflow even smoother.&lt;/p&gt;&lt;p data-block-key=&quot;1k922&quot;&gt;CI/CD tools vary widely in features and approaches, but at their core, the biggest distinctions boil down to two considerations:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;9tj4i&quot;&gt;Should CI maintenance be concentrated in a dedicated team or distributed among all developers in the project?&lt;/li&gt;&lt;li data-block-key=&quot;e9kq8&quot;&gt;Does your team prefer a self-managed solution or a fully-hosted cloud service?&lt;/li&gt;&lt;/ul&gt;&lt;p data-block-key=&quot;ev31j&quot;&gt;Answering these questions and understanding how they affect your workflows can help you choose a tool with the right balance between control, flexibility, needed expertise, and ease of maintenance.&lt;/p&gt;&lt;h2 id=&quot;buildbot:-centralized-and-customizable&quot; data-block-key=&quot;j99o0&quot;&gt;Buildbot: Centralized and customizable&lt;/h2&gt;&lt;p data-block-key=&quot;fdii1&quot;&gt;&lt;a href=&quot;https://www.buildbot.net/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Buildbot&lt;/a&gt; is an on-prem CI tool known for its centralized architecture, where all configurations and processes are managed in one place. It’s popular with teams that have similar workflows across multiple projects. Projects like Python, Blender, and LLVM use Buildbot to handle builds efficiently. Its centralized setup makes it easy to implement global changes, such as adding new tools or updating validation rules, with minimal disruption across all projects.&lt;/p&gt;&lt;p data-block-key=&quot;en1b9&quot;&gt;However, this centralized control comes with a trade-off: Substantial maintenance effort. You’ll likely need a dedicated administrator – especially as projects grow. Buildbot lacks a user-friendly interface, so you need to edit Python scripts and config files to make changes. And, for teams working with external clients or diverse user groups, it doesn’t separate users or projects into clean access groups.&lt;/p&gt;&lt;p data-block-key=&quot;1erbo&quot;&gt;Still, if you’ve got many similar projects with shared workflows and dependencies that need deep customization, Buildbot is an excellent choice, particularly for teams that have the resources to maintain it.&lt;/p&gt;&lt;h2 id=&quot;jenkins:-flexible-and-developer-friendly&quot; data-block-key=&quot;pe5lh&quot;&gt;Jenkins: Flexible and developer friendly&lt;/h2&gt;&lt;p data-block-key=&quot;7t6v8&quot;&gt;&lt;a href=&quot;https://www.jenkins.io/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Jenkins&lt;/a&gt; takes a different approach. It’s also an on-prem solution but with a more distributed approach to CI workflows. Unlike Buildbot, Jenkins allows teams to manage CI configurations, including builds and workflows, right in their own project repositories. This decentralized design makes it a strong fit for teams with diverse projects, tools, or languages that want to customize builds on a per-project basis.&lt;/p&gt;&lt;p data-block-key=&quot;3fb6s&quot;&gt;Jenkins is relatively easy to set up and use, thanks to its web-based interface for managing builds and configurations and its plug-in ecosystem that covers many common use cases. That said, this flexibility comes at a cost: Making global changes across projects can be more difficult in a decentralized setup, and certain customizations require Groovy scripting, which is less straightforward than Python.&lt;/p&gt;&lt;p data-block-key=&quot;73vfe&quot;&gt;Jenkins shines in environments with many unique workflows and tools, and its SaaS-like features, such as user and project management, make it a good choice for multi-client or collaborative teams. While a dedicated administrator isn’t always necessary for basic use cases, scaling and complex configurations benefit from having someone knowledgeable in Jenkins at the helm.&lt;/p&gt;&lt;h2 id=&quot;github-actions:-cloud-and-easy&quot; data-block-key=&quot;aduk8&quot;&gt;GitHub Actions: Cloud and easy&lt;/h2&gt;&lt;p data-block-key=&quot;4rlgl&quot;&gt;&lt;a href=&quot;https://github.com/features/actions&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;GitHub Actions (GHA)&lt;/a&gt; is a cloud-based CI/CD solution tightly integrated into the GitHub platform. Designed for simplicity, GHA provides pre-configured environments and scripts for common CI/CD tasks, making it easy for teams to get started. GHA is especially great for open-source projects, because it’s free for public repositories and requires no infrastructure maintenance.&lt;/p&gt;&lt;p data-block-key=&quot;bjjqg&quot;&gt;However, the platform is not without its limitations. Since GHA is tied exclusively to GitHub, it’s a no-go if you’re not on GitHub. And for private repositories, you’ll have to pay once you use up your free minutes, making it less appealing for budget-conscious projects. It’s also not as flexible as Jenkins or Buildbot for teams that need heavy customization or an on-prem solution.&lt;/p&gt;&lt;p data-block-key=&quot;2068p&quot;&gt;GHA is best for open-source teams or small projects already using GitHub. It’s also an excellent option for CI/CD beginners who want a streamlined, maintenance-free solution. For private projects with complex needs or teams that need platform flexibility, other tools like Buildbot or Jenkins might be a better fit.&lt;/p&gt;&lt;h2 id=&quot;ci-helpers:-cmake-presets-and-pre-commit&quot; data-block-key=&quot;oh2ap&quot;&gt;CI helpers: CMake presets and pre-commit&lt;/h2&gt;&lt;p data-block-key=&quot;eadna&quot;&gt;Even with a good CI/CD system, there are a couple of tools I’d recommend to make life easier. Helper tools like CMake Presets and &lt;a href=&quot;https://pre-commit.com/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;pre-commit&lt;/a&gt; can significantly streamline workflows, particularly for desktop and embedded development.&lt;/p&gt;&lt;p data-block-key=&quot;db2i&quot;&gt;&lt;b&gt;CMake Presets&lt;/b&gt; is an extension of the popular &lt;a href=&quot;https://cmake.org/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;CMake&lt;/a&gt; build tool that simplifies managing multiple build configurations. By letting you define specific presets for tasks such as local-development or CI builds, CMake Presets cleanly separates these processes, reducing complexity in large projects where environments and dependencies are shared across different workflows.&lt;/p&gt;&lt;p data-block-key=&quot;80jea&quot;&gt;Similarly, &lt;b&gt;pre-commit&lt;/b&gt; is a framework for managing Git pre-commit hooks, and it’s a game-changer for catching issues early. You can use it to run static analysis, enforce code formatting, and check for common errors before any files are committed. And because it runs locally, it reduces the load on your CI systems and gives developers quick feedback, improving code quality and speeding up reviews.&lt;/p&gt;&lt;h2 id=&quot;so-which-tool-is-best-for-you&quot; data-block-key=&quot;sm69z&quot;&gt;So, which tool is best for you?&lt;/h2&gt;&lt;p data-block-key=&quot;3bb9l&quot;&gt;The best CI/CD solution depends on your team’s needs and workflow complexity. Buildbot is great if you’ve got a lot of similar projects and want full control over your CI pipeline. Jenkins is better if you’re juggling a mix of projects and need something flexible and easy to manage. And if you’re already on GitHub, GitHub Actions is the fastest way to get up and running.&lt;/p&gt;&lt;p data-block-key=&quot;5pvu4&quot;&gt;No matter which tool you choose, pairing it with helpers like CMake Presets and pre-commit can make your workflows even better. At the end of the day, the best CI/CD setup is the one that fits your projects, your team, and the way you like to work.&lt;/p&gt;&lt;p data-block-key=&quot;7fad8&quot;&gt;For a deeper dive into these topics and more advice on setting up your CI/CD pipeline, take a look at our &lt;a href=&quot;https://www.kdab.com/publications/bestpractices/best-practices-ci-cd.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;CI/CD Best Practice whitepaper&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/cicd-simplified-comparing-buildbot-jenkins-and-github-actions/&quot;&gt;CI/CD Simplified: Comparing Buildbot, Jenkins, and GitHub Actions&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Jan Marker</dc:creator><category>performance</category><category>tools</category></item></channel></rss>