January 19, 2002
"Walter" <walter@digitalmars.com> wrote in message news:a2ad4l$128$1@digitaldaemon.com...

> COM requires:
> 1) the first entry in an object is a vptr
> 2) the layout of the vtbl[] is exactly like C++ single inheritance
> 3) stdcall calling conventions
> 4) AddRef() and Release() memory management.

> D Interfaces fail (1), (3), (4).

Why (3)? Isn't extern(Windows) applicable to methods? I remember
you used extern(C) for OutBuffer.printf() (and so did I for
Stream.printf(), then =)), and it worked...

> The solution is to recognize a special root object (strangely enough
called
> "IUnknown" <g>). Deriving from this, instead of from Object, means you
wind
> up with a COM style vtbl[], and it also sets the function calling conventions to stdcall. This has some effects like you can't do a
.classinfo
> on a COM object (no rtti). COM objects are also reference counted, and are not on the garbage collected heap.

It's pretty okay.

> It will be possible to write DLLs in D, I just haven't written the
necessary
> library support for it yet.

...which is pretty possible to do ourselves, right? Isn't is as simple as providing our own version of dmain2.d?


January 19, 2002
"Walter" <walter@digitalmars.com> wrote in message news:a2ad7v$12e$1@digitaldaemon.com...

> It's a great idea, but doesn't work if functions are overloaded. -Walter

Overloaded ones could be skipped:

    enum vtable
    {
        foo,
        // foo
        bar = foo + 2,
        // bar,
        // bar,
        baz = bar + 3,
    }


January 19, 2002
Or even:

    enum vtable
    {
        foo,
        // bar,
        // bar,
        // bar,
        baz = foo + 4
    }

So no pointers for overloaded functions.
Who needs them anyhow? =)


January 19, 2002
Walter wrote:

> The solution is to recognize a special root object (strangely enough called
> "IUnknown" <g>). [details omitted]
> 
> It sounds wartier than it actually is.


Actually, from the outside it sounds pretty elegant, even if
it's warty on the inside.

-RB

January 19, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:a2aes3$24o$1@digitaldaemon.com...
> "Walter" <walter@digitalmars.com> wrote in message news:a2ad4l$128$1@digitaldaemon.com...
>
> > COM requires:
> > 1) the first entry in an object is a vptr
> > 2) the layout of the vtbl[] is exactly like C++ single inheritance
> > 3) stdcall calling conventions
> > 4) AddRef() and Release() memory management.
>
> > D Interfaces fail (1), (3), (4).
>
> Why (3)? Isn't extern(Windows) applicable to methods? I remember
> you used extern(C) for OutBuffer.printf() (and so did I for
> Stream.printf(), then =)), and it worked...

Yes, the extern works with methods. It just isn't the default.

> > The solution is to recognize a special root object (strangely enough
> called
> > "IUnknown" <g>). Deriving from this, instead of from Object, means you
> wind
> > up with a COM style vtbl[], and it also sets the function calling conventions to stdcall. This has some effects like you can't do a
> .classinfo
> > on a COM object (no rtti). COM objects are also reference counted, and
are
> > not on the garbage collected heap.
>
> It's pretty okay.
>
> > It will be possible to write DLLs in D, I just haven't written the
> necessary
> > library support for it yet.
>
> ...which is pretty possible to do ourselves, right? Isn't is as simple as providing our own version of dmain2.d?

Yeah, that's about it.



January 19, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:a2aik2$4l7$1@digitaldaemon.com...
> Or even:
>
>     enum vtable
>     {
>         foo,
>         // bar,
>         // bar,
>         // bar,
>         baz = foo + 4
>     }
>
> So no pointers for overloaded functions.
> Who needs them anyhow? =)

I suppose this would be rather iky?

enum vtable
{
    foo_v,
    bar_i,
    bar_icda,
    bar_f,
    baz
} // i = int, c = char, da = dynamic array, f = float

or better yet

thing.classinfo.method{"int bar(int)"];

thing.classinfo.method{"int bar(char[])"];

Walter, are functions in D overloadable on return type?






January 19, 2002
"Patrick Down" <pdown@austin.rr.com> wrote in message news:a2b3lv$f6a$1@digitaldaemon.com...

> I suppose this would be rather iky?
>
> enum vtable
> {
>     foo_v,
>     bar_i,
>     bar_icda,
>     bar_f,
>     baz
> } // i = int, c = char, da = dynamic array, f = float

Yep, because imagine a user trying to build the name
of the function out of its arguments (because he
doesn't see that compiler-generated enum).

I must say that, having worked with Delphi for a long time, I don't remember any program that took a function pointer to an overloaded function. This is something that can be sacrificed, IMO.

> thing.classinfo.method{"int bar(int)"];
> thing.classinfo.method{"int bar(char[])"];

This moves most of the code to run-time (since with
enum we already have positions in vtable, and here
it has to find a key in an associative array).





January 19, 2002
Okay, so it turned out to be not that simple...

Since extern(D) - the default - doesn't specify order of
arguments strictly, it cannot be used in low-level, so
methods we want to get pointers to have to be extern(C).
The problem is, such methods don't reside in the vtable -
they are called directly! So, once again, the only way
to get a pointer to it is some special operator, or
something...


January 19, 2002
I should have thought twice before posting... =)

Now, I came to the working solution, which seems perferctly portable. The idea is to define a base class for all classes that want pointers to their functions (most frequently it's class itself who uses pointers to its methods anyhow), and let it contain a dummy entry in the vtable - just an empty function - which then gets substituted by whatever pointer we have. So:

    class Component: Object
    {
        // should be the very first
        void _event_callback(void* ptr) { }
    }
    Component obj;
    ...
    // put pointer to our callback method into the vtable...
    obj.classinfo.vtable[Object.classinfo.vtable.length] =
our_function_pointer;
    // ...and call it!
    obj._event_callback(pointer_to_some_data);

Unfortunately D doesn't allow class.classinfo (only object.classinfo) -
btw a feature request, Walter! =) - but nothing stops us from creating
a temporary Object in static constructor and getting it's vtable.length...

So if we get the method-list enumeration, method pointers can be considered there.


January 19, 2002
"Russell Borogove" <kaleja@estarcion.com> wrote in message news:3C48E52C.10801@estarcion.com...
> Walter wrote:
>
> > The solution is to recognize a special root object (strangely enough
called
> > "IUnknown" <g>). [details omitted]
> >
> > It sounds wartier than it actually is.
>
>
> Actually, from the outside it sounds pretty elegant, even if it's warty on the inside.
>
> -RB


Indeed, it does sound pretty elegant! Is the IUnknown root object part of the standard D libraries? Très Cool!

I was delving into COM just before I learned of D, and I like
both of them a lot, but I had I concern I couldn't mix coding
with the two, so that would have been a shame.
It is great to hear that not only is it supported, but that it is
actually cleaner to do than in C++!


--
Stijn
OddesE_XYZ@hotmail.com
http://OddesE.cjb.net
__________________________________________
Remove _XYZ from my address when replying by mail