Generating D files from C or C++ header files is a difficult endeavor. However, the converse process of generating C++ header files from D source files is easier to approach, and very useful.
Possible uses include migrating a large C++ codebase to D in small steps without needing to deal with declaration duplication across D code and C++ legacy code. (The dmd compiler itself may use the tool.) Using D as source and translating from D to C++ gives a robust unique point of maintenance.
Here are a few requirements:
* dtoh takes a D file as input and generates C++ declarations for all pertinent function and class declarations in the D file.
* Accepted declarations: data, functions, classes, and interfaces for all types that have a C++ correspondent.
* D declarations that cannot be translated into C++ will be ignored.
* In order to stay decoupled from the compiler, dtoh should generate C++ code from the JSON output of the D compiler.
* For make friendliness, dtoh should overwrite its output if and only if the generated output is different from the existing output.
* The generated C++ code should be human readable (nicely indented etc) and use good C++ practices (e.g. include guards etc).
* C++11 generation is default, there should be an option to generate C++98.
The tool would be in the tools/ repository and distributed alongside with the compiler in source and binary forms.
Comment #1 by alex — 2013-01-09T00:14:55Z
So how do you see this working overall? Generate a bunch of mangled declarations in the resulting .h and then generate some nice C++-y wrappers around them?
> * C++11 generation is default, there should be an option to generate C++98.
Virtually every C++ compiler in existence supports C++03, so why not that?
Comment #2 by ibuclaw — 2013-01-09T00:20:53Z
(In reply to comment #1)
> So how do you see this working overall? Generate a bunch of mangled
> declarations in the resulting .h and then generate some nice C++-y wrappers
> around them?
>
> > * C++11 generation is default, there should be an option to generate C++98.
>
> Virtually every C++ compiler in existence supports C++03, so why not that?
It's true, even GCC's -std=c++98 switch is just an alias for -std=c++03
Comment #3 by andrei — 2013-01-09T00:22:31Z
(In reply to comment #1)
> So how do you see this working overall? Generate a bunch of mangled
> declarations in the resulting .h and then generate some nice C++-y wrappers
> around them?
No, just generate declarations for extern(C++) names. This is a tool for people who want to interface with C++ and know what steps to take.
> > * C++11 generation is default, there should be an option to generate C++98.
>
> Virtually every C++ compiler in existence supports C++03, so why not that?
OK
Comment #4 by andrej.mitrovich — 2013-01-09T08:58:26Z
(In reply to comment #0)
> * In order to stay decoupled from the compiler, dtoh should generate C++ code
from the JSON output of the D compiler.
JSON output still needs fixing, see https://github.com/D-Programming-Language/dmd/pull/1179
Comment #5 by destructionator — 2013-01-09T09:07:41Z
I just slapped something together very very quickly. It works for a couple simple things I've tried on linux: simple functions and interfaces.
http://arsdnet.net/dcode/dtocpp.zip
includes a little test program (test.c, test.cpp, and testcpp.d), a makefile for it, and of course, the main app, dtoh.d.
dmd dtoh.d
make
The makefile will regenerate testcpp.json and run dtoh to build testcpp.h.
I just realized, I guess I should add POD structs too, but I have real work to get back to now.
Comment #6 by andrei — 2013-01-09T10:14:10Z
(In reply to comment #5)
> I just slapped something together very very quickly. It works for a couple
> simple things I've tried on linux: simple functions and interfaces.
>
> http://arsdnet.net/dcode/dtocpp.zip
>
> includes a little test program (test.c, test.cpp, and testcpp.d), a makefile
> for it, and of course, the main app, dtoh.d.
>
> dmd dtoh.d
> make
>
> The makefile will regenerate testcpp.json and run dtoh to build testcpp.h.
>
>
> I just realized, I guess I should add POD structs too, but I have real work to
> get back to now.
Great. When you'll assess your work is in reviewable form, you may want to submit it as a pull request to github.com/D-Programming-Language/tools. Once we have a good initial codebase others can work on it.
Comment #7 by destructionator — 2013-01-09T11:16:49Z
work is boring so i updated the zip instead. Hit a few problems, we'll really need to improve dmd's json output (I vote for that pull request!) to go much further than this I think. Maybe fix up forward declarations but meh.
Turning import into include needs more json from dmd as well, and that's going to be nice to have for real work (though not strictly necessary... the user could always #include everything in the main file).
Anyway here it is:
http://arsdnet.net/dcode/dtocpp.zip
Now structs are outputted too, as plain data skipping any functions (which I'm pretty sure should work anyway), and types are translated a little differently.
If you write your declarations in D, whether you implement them in C++ or D doesn't matter, this is kinda cool for going both ways.
But yeah I think this is about as good as we're going to get until that dmd pull request for json happens.
Comment #8 by andrei — 2013-01-09T11:22:05Z
(In reply to comment #7)
> Turning import into include needs more json from dmd as well
Please submit to bugzilla anything you have, and fill the "depends on" field above to mark the dependency. Thanks!
Comment #9 by destructionator — 2013-01-15T10:11:18Z
Comment #10 by destructionator — 2013-11-27T11:43:21Z
Are there any more substantial comments on the code I wrote in January? I just tried to use it again, and there's some small updates needed. dmd's json output has changed, it outputs mangles instead of types now! Weird. Of course, the substantial stuff still isn't there - I'm wondering if it wouldn't be better to do this with traits instead of the json.
Right now, the way it works is you do
dmd -X file.d
dtocpp file.json
But, maybe we should do:
translator.d:
import dtocpp;
import module_you_want_to_convert;
mixin Convert!(module_you_want_to_convert);
dmd translator.d dtocpp.d needed_modules.d
./translator
idk, the json is close to good enough, there's just still things I wish it did better. It really needs to list enum values, if nothing else, to make them useful. What I did before with that was to just skip enums.
Comment #11 by destructionator — 2013-11-27T19:51:37Z
I cleaned up and updated my old code so it works with new dmd again:
http://arsdnet.net/dcode/dtoh.zip
There's still some fixmes in there i can fix, but if anyone gets a chance to take a look and let me know if it is ok so far, i'd appreciate it.
Comment #12 by code — 2013-12-04T13:36:50Z
(In reply to comment #11)
> I cleaned up and updated my old code so it works with new dmd again:
>
> http://arsdnet.net/dcode/dtoh.zip
>
> There's still some fixmes in there i can fix, but if anyone gets a chance to
> take a look and let me know if it is ok so far, i'd appreciate it.
How about reopening a pull request to tools.
Comment #13 by destructionator — 2014-02-10T20:55:50Z