June 01, 2006
Yet another feature update.  bcd.gen now generates const ints or const doubles for /SOME/ #define-type stupid-consts.

 - Gregor Richards
June 02, 2006
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
June 03, 2006
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


June 04, 2006
BLS wrote:
> Hello Gregor,
> What about a timeout ?
In a few weeks I'll be on vacation for three weeks :)

> But I guess you can not expect mercy. So what about porting libglade......
Done, in bindings/bcd/libglade2

> and of couse the gnomedb project ?
I may look at it.  Finals are coming up, so I may have no time, but we'll see.

> Hell, you have done a damned good job !!
Thanks :)

> bjoern
> 
June 07, 2006
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
June 07, 2006
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.
June 07, 2006
Erm, typo in my explanation.  The D class A_R derives from the D class A.

 - Gregor Richards
1 2
Next ›   Last »