Creating C language bindings for Qt - Where do I start?
-
I'm very interested in also creating C language bindings for Qt6, and I'm well aware that the Qt libraries are written entirely in C++.
I'm also very inexperienced with the Qt6 submodule repos and where their necessary or main functions are located in each submodule.
I'm well aware that it's entirely possible to create C wrappers around C++ functions, and to convert classes into a C struct, as explained in here and this note in cimgui seen here.
But if anyone knows where to start in each of the Qt submodules and show me where I need to begin, I will begin work on this massive project.
Thank you in advance!
-
@Platinum-Lucario Maybe
corelib
is wanted for everything else? Sounds pretty fundamental to me. -
Good morning,
Maybe start by telling us what you actually want to achieve. What’s the use case?- Do you want to write C bindings for all of Qt? For whom and why?
- Or do you have a C based application that needs a Ui? Do you want to port it from a C based Ui framework like e.g. GTK?
-
Thank you for asking!
There is quite a few things I'd like to achieve with this.
- I aim to build a generator to generate C APIs for the Qt framework.
- The first use case would be to make it more easier for other language bindings (such as C#) to bind to.
- To generate C libraries that use operate in the same way as the C++ code.
- Another use case would be to have actual C APIs generated for the Qt libraries, making it easier for projects written in C to use such functions.
Currently for the Qt6 C# bindings project, it's a fork of QtSharp (which is going to be updated to modern .NET code), but in the long term, I'd like to use the generated C libraries for a rewrite of my forked project.
-
Interesting use case. I'd start with qtbase in that case. All other submodules depend on it.
-
That's definitely a great idea! I'll start with the qtbase submodule. I was actually looking into qtbase earlier.
Now I'm just curious as to which headers are the most important ones in qtbase to start with? There's plenty of directories, there's:
- 3rdparty
- android
- assets
- concurrent
- corelib
- dbus
- entrypoint
- gui
- network
- opengl
- openglwidgets
- platformsupport
- plugins
- printsupport
- sql
- testlib
- tools
- widgets
- xml
From what I can tell, entrypoint is windows-specific, android - as the name implies seems to be for the Android OS, 3rdparty is likely many 3rd party library code that it relies on, and gui has many directories in there too:
- accessible
- animation
- compat
- doc - most likely for documentation
- image
- itemmodels
- kernel
- math3d
- opengl - most likely for OpenGL 3D rendering
- painting
- platform
- rhi
- text
- util
- vulkan - most likely for Vulkan 3D rendering
But the big question is, which one is the most important one should I start with in qtbase?
-
@Platinum-Lucario Maybe
corelib
is wanted for everything else? Sounds pretty fundamental to me. -
@JonB That's a great starting point! I'll focus on that one first.
-
-
@Platinum-Lucario said in Creating C language bindings for Qt - Where do I start?:
and to convert classes into a C struct,
I don't see where you'd actually want C structs. The best you can do is hide everything behind opaque handles. Like your first link is showing they are using just a plain
void*
instead of introducing a C struct. One problem, though, is that this only works for objects created on the heap. This is alright for everything that you derive from QObject. In many cases these have to live on the heap. However, it gets more complicated when you want to port QString or QVector. A lot of times I would just allocate these on the stack instead of the heap. This gives much better performance. There is also the question if you'd rather like a plain C-style interface instead of Qt types. From C I'd prefer to be able to provide a plainconst char *
where the C++ interface expects aQString
(and also just a plain array where a QVector/QList is expected). You have to decide for yourself what you'd rather want here.Concerning functions you have to think about how to resolve function overloading. In C you need separate names for each. At least with modern C you can simplify the usage by using
_Generic
. -
@SimonSchroeder said in Creating C language bindings for Qt - Where do I start?:
using just a plain void* instead of introducing a C struct
@Platinum-Lucario should read and be aware of the discussion we had recently in QGraphicsTextItem * and void * conversion error and the conclusion at https://forum.qt.io/post/815140. The gist is that where Qt uses C++ multiple inheritance you lose information and go wrong if you are not careful about what you pass as a C
void *
.