www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - bcd.gen: A generator for bindings to C++ in D

reply Gregor Richards <Richards codu.org> writes:
[Gregor is insane 8-D]

I'm writing a generator for bindings to C++ in D.  It's in a 
semi-working state right now, so I figured I'd tell people it exists.

It works by using GCCXML to parse the C++ header, then making extern "C" 
wrapper classes for every function in .cc files, then calling those from 
.d files made to mimic the layout of the C++ classes.  The code is ugly, 
but to the end-user it's entirely transparent.  Because it mimics the 
layout of the C++ classes, if you know how to use a library in C++, it 
should be very similar in D (with BCD bindings).

Before you ask, no, it does not support:

  * Templates
  * Multiple inheritance
  * That other crazy C++ feature you're thinking about right now

It's still in a VERY beta stage, but it's working at least enough to get 
a binding to FLTK2 and make a window with a widget.  That's something :)

It's hosted on dsource, at http://www.dsource.org/projects/bcd

  - Gregor Richards
May 28 2006
next sibling parent Gregor Richards <Richards codu.org> writes:
bcd.gen now supports C as well as C++.  bcd/libxml2 is a binding to libxml2.

  - Gregor Richards
May 28 2006
prev sibling next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Gregor Richards wrote:

 It's hosted on dsource, at http://www.dsource.org/projects/bcd

Tried to use the web page to find a download, but got this instead: could not translate host name "localhost" to address: Name or service not known In the end I just gave up and hacked an non-svn address together: svn checkout http://svn.dsource.org/projects/bcd/trunk Which worked better... Is there a tarball or is SVN supposed to work ? --anders
May 29 2006
parent reply Gregor Richards <Richards codu.org> writes:
Anders F Björklund wrote:
 Which worked better... Is there a tarball or is SVN supposed to work ?
 --anders

It's not in releasable state yet, so just SVN. SVN should work. - Gregor Richards
May 29 2006
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Gregor Richards wrote:

 It's not in releasable state yet, so just SVN.  SVN should work.

Actually I meant like a "daily tarball" from the SVN repository, but using the HTTP protocol instead of SVN made it limp along... --anders
May 29 2006
parent Gregor Richards <Richards codu.org> writes:
Anders F Björklund wrote:
 Gregor Richards wrote:
 
 It's not in releasable state yet, so just SVN.  SVN should work.

Actually I meant like a "daily tarball" from the SVN repository, but using the HTTP protocol instead of SVN made it limp along... --anders

Probably a good idea. I wonder if that can be done automatically through Trac ... if not, I can set up a cronjob. - Gregor Richards
May 29 2006
prev sibling next sibling parent reply Gregor Richards <Richards codu.org> writes:
Some more BCD news.

A) BCD now supports enough C to bind GTK+.  Hooplah.

B) Killer feature: You can reflect D classes into C++, and instantiate 
C++ templates with them.  There are limitations (it only reflects 
operators, and not all operators are the same between the two), but it 
does work.

C) One of these days, I'll document bcd.gen.  Really.  Maybe.

  - Gregor Richards
May 31 2006
next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Gregor Richards wrote:
 Some more BCD news.
 
 A) BCD now supports enough C to bind GTK+.  Hooplah.

Pardon my use of profanity, but: Holy sh*t!
 
 B) Killer feature: You can reflect D classes into C++, and instantiate
 C++ templates with them.  There are limitations (it only reflects
 operators, and not all operators are the same between the two), but it
 does work.
 

Just... wow. Seriously, this is awesome stuff. Fantastic work. -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Jun 01 2006
prev sibling parent reply clayasaurus <clayasaurus gmail.com> writes:
Gregor Richards wrote:
 Some more BCD news.
 
 A) BCD now supports enough C to bind GTK+.  Hooplah.
 
 B) Killer feature: You can reflect D classes into C++, and instantiate 
 C++ templates with them.  There are limitations (it only reflects 
 operators, and not all operators are the same between the two), but it 
 does work.
 
 C) One of these days, I'll document bcd.gen.  Really.  Maybe.
 
  - Gregor Richards

You should give libpng a whirl, it is written in C and would be nice but a real headache to manually port to D.
Jun 01 2006
parent Gregor Richards <Richards codu.org> writes:
clayasaurus wrote:
 You should give libpng a whirl, it is written in C and would be nice but 
 a real headache to manually port to D.

Unfortunately, libpng uses setjmp/longjmp, so binding it would involve making a system-independent binding to those, first ... that would certainly be possible, but ow :) - Gregor Richards PS: The main difficulty in making a system-independent binding to setjmp/longjmp is that jmpbufs are different sizes on every system. They're 24 bytes on x86/Linux, 64 bytes (IIRC) on x86/Windows, and a different size on just about every system. Pfft.
Jun 01 2006
prev sibling next sibling parent Gregor Richards <Richards codu.org> writes:
Yet another feature update.  bcd.gen now generates const ints or const 
doubles for /SOME/ #define-type stupid-consts.

  - Gregor Richards
Jun 01 2006
prev sibling parent reply Gregor Richards <Richards codu.org> writes:
It is now possible to derive D classes from C++ classes in 
bcd.gen-generated bindings.  This should open the doors to libraries 
like Qt and WxWidgets.

My head hurts.

  - Gregor Richards
Jun 02 2006
next sibling parent reply "BLS" <lietz wanadoo.fr> writes:
Hello Gregor,
What about a timeout ?
But I guess you can not expect mercy. So what about porting libglade......
and of couse the gnomedb project ?
Hell, you have done a damned good job !!
bjoern

"Gregor Richards" <Richards codu.org> schreef in bericht
news:e5pss7$1l02$1 digitaldaemon.com...
 It is now possible to derive D classes from C++ classes in
 bcd.gen-generated bindings.  This should open the doors to libraries
 like Qt and WxWidgets.

 My head hurts.

   - Gregor Richards

Jun 03 2006
parent Gregor Richards <Richards codu.org> writes:
BLS wrote:
 Hello Gregor,
 What about a timeout ?

 But I guess you can not expect mercy. So what about porting libglade......

 and of couse the gnomedb project ?

we'll see.
 Hell, you have done a damned good job !!

 bjoern
 

Jun 04 2006
prev sibling parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Gregor Richards wrote:
 It is now possible to derive D classes from C++ classes in 
 bcd.gen-generated bindings. 

Whoa, how is that possible? Wait, better yet could you clarify me a bit more on what exactly is "derive D classes from C++ classes" first? And perhaps give an example? (sorry if I'm being a bit lazy to look it up myself) -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jun 07 2006
parent reply Gregor Richards <Richards codu.org> writes:
Bruno Medeiros wrote:
 Gregor Richards wrote:
 
 It is now possible to derive D classes from C++ classes in 
 bcd.gen-generated bindings. 

Whoa, how is that possible? Wait, better yet could you clarify me a bit more on what exactly is "derive D classes from C++ classes" first? And perhaps give an example?

Sure! First, the transparent programmer's perspective: C++ code: {{ class A { virtual void foo(); virtual int bar(int); } }} Generated D code: {{ class A { void foo() { ... } int bar(int) { ... } } class A_R { this() { /* very extra-special constructor stuff here */ } } }} To derive a D class from the C++ class A: {{ class MyClass : A_R { void foo() { // whatever you want } } }} Now, if you pass a MyClass as an A (which is valid because it's derived from it), foo will be overridden, and the C++ calls to foo will hit your foo, not C++'s! Now, the nasty internals: Supplied C++ code: {{ class A { virtual void foo(); virtual int bar(int); } }} Generated C++ code: {{ extern "C" int __BCD_CHECK_A_foo(void *); extern "C" void __BCD_A_foo(void *); extern "C" int __BCD_CHECK_A_bar(void *); extern "C" int __BCD_A_bar(void *, int); /* the names above are actually generated unique names */ class __A_DRefelction { /* this is actually a name which is generated and guaranteed to be unique */ void foo() { if (__BCD_CHECK_A_foo(__D_data)) { __BCD_A_foo(__D_data); } else { A::foo(); } } int bar(int _1) { if (__BCD_CHECK_A_bar(__D_data)) { return __BCD_A_bar(__D_data, _1); } else { return A::bar(_1); } } } }} Notes: 1) __D_data is set by the D constructor 2) __BCD_CHECK_* are functions implemented in D to check whether a particular method has been overridden in a D class or not. 3) __BCD_* are generated wrapper functions to the D methods. Generated D code: {{ class A { void foo() { ... } int bar(int) { ... } } class A_R { this() { /* very extra-special constructor stuff here */ } } extern (C) int __BCD_CHECK_A_foo(A_R This) { /* this is a simplification of the real, overcomplicated code */ return cast(int) (This.foo != A_R.foo); } extern (C) void __BCD_A_foo(A_R This) { This.foo(); } extern (C) int __BCD_CHECK_A_bar(A_R This) { /* again, a simplification */ return cast(int) (This.bar != A_R.bar); } extern (C) int __BCD_A_bar(A_R This, int _1) { return This.bar(_1); } }} Basically, in English: For every class in C++, a class is made which overrides every virtual function with checks into D. If it's not overridden by D, it calls the lower virtual function (just like it would do if it wasn't overridden at all). For every class in D, a class is made which, rather than generating the base C++ class, generates the previously-mentioned reflection class (the reason for not doing this as the general case is efficiency) For every virtual function, a wrapper is made in D to check whether that function has been overridden in a D class. I'm not sure if that helped at all. Hopefully it did :)
 
 (sorry if I'm being a bit lazy to look it up myself)
 

The code is very ugly ... probably wiser just to ask ;) - Gregor Richards PS: For those that are interested about progress: wxWidgets uses method pointers. I'm not sure if I can bind these, as they're very inconsistent in C++. I haven't actually tried to bind Qt yet, but it's more promising than wxWidgets.
Jun 07 2006
parent Gregor Richards <Richards codu.org> writes:
Erm, typo in my explanation.  The D class A_R derives from the D class A.

  - Gregor Richards
Jun 07 2006