title: Calling a Rust libary through a thread in Qt
body: <p>I'm making a Qt frontend for a Rust libary which exposes a C++ function that blocks the execution thread it resides in, but allows to pass a callback function for communication between the two ends.</p>
  
  <p>So I thought of using Qt's threading technologies to make the library execution on another thread, and I'd like to do it <em>with the least amount of modifications as possible to the Rust library</em>.</p>
  
  <p>This is my approach using QThreads:</p>
  
  <p>backend.cpp:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>typedef void(*callback_t)(void *,const char *);
  extern "C" call_rust_library(const char *config, void *cb_data, callback_t cb);
  
  template&lt;typename T&gt;
  void call_wrapper(void *ptr, const char*data) {
      (*static_cast&lt;T*&gt;(ptr))(data);
  }
  
  class BackEnd : public QObject {
      Q_OBJECT
  public slots:
      void do_computations(ConfigObject *config) {
          //...parse configuration from the frontend...
          char* parsed_configuration;
          BackEnd* backend = this;
  
          auto callback = [backend](char* data) {
              //...process obtained data from the library...
              QString type,contents;
              backend-&gt;emit send_message(type,contents);
          }
  
          call_rust_library(parsed_configuration,(void *)&amp;callback,call_wrapper&lt;decltype(callback)&gt;);
      }
  signals:
      void send_message(QString type, QString contents);
  }
  </code></pre>
  
  <p>frontend.cpp:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>class FrontEnd : public QMainWindow {
      Q_OBJECT
      QThread thread;
      ConfigObject *config;
  public slots:
      void process_message(QString type, QString contents) {
          //...do GUI things with the message
      }
  private slots:
      void on_request_start_thread() {
          // called by a GUI event
          BackEnd* backend = new BackEnd;
          backend-&gt;moveToThread(&amp;thread);
          connect(&amp;thread,&amp;QThread::finished,backend,&amp;QObject::deleteLater);
          connect(this,&amp;FrontEnd::run_thread,backend,&amp;BackEnd::do_computations);
          connect(backend,&amp;BackEnd::send_message,frontend,&amp;FrontEnd::process_message);
          emit run_thread(config)
      }
  signals:
      void run_thread(ConfigObject *config);
  }
  </code></pre>
  
  <p>However I have a couple of problems with this:</p>
  
  <ul>
  <li>First off, nothing from the backend gets executed. If I don't move the BackEnd object to another thread it does seem to run everything but crashes somewhere on a system library (my best guess is that is because Qt forbids blocking the GUI thread and/or handling GUI functions from another thread).</li>
  <li>How would Qt be able to abort the Rust library execution thread? (via closing the application or the user clicking a button) The Rust library doesn't seem to expose any mechanism to stop its execution, so I'm wondering if I have to make modifications to the library to expose a function to abort whatever it's doing.</li>
  </ul>
  
  <p>Recently I've found <a href="https://gitlab.com/bloom42/research/rust_gui_ecosystem/tree/master/qt_cpp" rel="nofollow noreferrer">this example repository</a> that allows for binding Qt with Rust libraries but doesn't seem to delve into multithreading, and might require my project to be ported from CMake to qmake. But from my understanding the Rust executions should be residing in another thread, so I'm not sure how is it achieved here.</p>