C++ Binding Generator

w0rp devw0rp at gmail.com
Sun Feb 23 13:23:18 PST 2014


https://github.com/w0rp/dqt

I have been working on my generator over the past few weeks, and 
extensively this weekend. It took many hours of work, but I just 
got generation of D source files from SMOKE data to work. Here is 
what it does and roughly how it works.

1. Earlier on, SMOKE is by a third party to generate a dynamic 
library. This library contains data held in a "Smoke" class 
defined in C++, which functions provided for creating, deleting, 
and getting a reference to the pointer for the class with what 
are *supposed* to be functions with C linkage. (I had to wrap 
them anyway with my own functions due to issues.)
2. Because the class members in Smoke are all C primitives, I can 
match the layout with a struct in D and load everything from the 
struct in D code. At the time of generation, I copy everything I 
need out of the struct into a saner representation in D, which I 
have called "SmokeContainer."
3. SmokeContainer is supposed to tell you everything you need to 
know to make generation work. So I use that data and pass it to 
my class which handles generation of D source files, 
"SmokeGenerator." It does all kinds of work to translate C++ 
classes from the SMOKE data to D code, with some ability for 
customisation like ignoring certain types or classes, replacing 
classes with different ones in D or just wrappers for generating 
them, etc.
4. The SmokeGenerator spits out the D source files and requires 
having a "SmokeLoader" defined in prefix D file, which loads the 
same SMOKE data again at runtime for finding the class method 
pointers needed to call C++ functions and so on.
5. You run a D program which uses the generated D source files 
and now you have C++ code being run from D.

While my project is actually called DQt above and the motivation 
for it is to get Qt working in D, I have written it all in such a 
way as to make the Qt specific part of the code and the general 
case SMOKE binding stuff loosely coupled. The only Qt specific 
stuff now lies in some C++ code needed for certain circumstances, 
(like wrapping QString) a few pre-baked D source files used as 
finishing touches for the generation specific to Qt, and the 
current test programs which generate code and run Hello World 
respectively. I shouldn't have too much trouble moving most of 
this stuff into a "dsmoke" repository instead.

If you want to try out running Hello World from the generated 
code yourself, and you're willing to work around my sloppy 
project structure, do this.

1. Build smokegen and smokeqt. I wrote two guides for Linux and 
Windows on this.
    1. Linux: 
https://github.com/w0rp/dqt/blob/master/doc/smoke_linux_build_guide.rst
    2. Windows: 
https://github.com/w0rp/dqt/blob/master/doc/smoke_win32_build_guide.rst
2. Use CMake to build my code. I think 'cmake . && make' will do 
the job on Linux, if you're in my project directory.
3. Put 'libsmoke_cwrapper' in your library path. I make it easy 
on myself by copying it out of the lib/ directory into src/ and 
by running 'export LD_LIBRARY_PATH=.' Not the best way, but it's 
a quick way to get it going.
4. 'rdmd -g -Llibsmoke_cwrapper.so -d -debug -w new_test.d' Will 
run the generator and spit some stuff into src/dqt for now.
5. 'rdmd -Llibsmoke_cwrapper.so -d smoke_test.d' will now run the 
Hello World program, supposing everything else went well.

I am going to continue working on this. There are some things to 
iron out and a lot of interesting work ahead. Hopefully I can get 
a somewhat usable Qt in D library out of this.


More information about the Digitalmars-d mailing list