www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - COM/OLE advanced questions

reply Guillaume Piolat <contact spam.com> writes:
I wonder if anyone has used COM in dlang extensively.

Context: I must use COM FFI interfacing on systems that aren't 
necessarily  Windows. It is essential that the layout of 
interfaces and classes are the same than in equivalent C++ 
objects.


Question 1. Is it mandatory to inherit from 
core.sys.windows.unknwn.IUnknown, or just having an interface 
named "IUnknown" validate it for being a COM interface?

    If yes, then how am I supposed to use COM interfaces in other 
OSes? core.sys.windows.unknwn.IUnknown is defined under 
version(Windows).

    I wonder what the exact compiler hook is.


Question 2. If this fails, may I emulate COM vtable layout with 
extern(C++) class? I wonder what the exact differences are anyway 
between extern(C++) and the special IUnknown.


Question 3. It seems I can inherit both from A D object and a COM 
interface. What will be the choosen layout?
Nov 02
next sibling parent Daniel Kozak <kozzi11 gmail.com> writes:
AFAIK you can only use COM from windows anyway. OK I have been using them
from linux but only with WINE help.

On Thu, Nov 2, 2017 at 3:22 PM, Guillaume Piolat via Digitalmars-d-learn <
digitalmars-d-learn puremagic.com> wrote:

 I wonder if anyone has used COM in dlang extensively.

 Context: I must use COM FFI interfacing on systems that aren't
 necessarily  Windows. It is essential that the layout of interfaces and
 classes are the same than in equivalent C++ objects.


 Question 1. Is it mandatory to inherit from core.sys.windows.unknwn.IUnknown,
 or just having an interface named "IUnknown" validate it for being a COM
 interface?

    If yes, then how am I supposed to use COM interfaces in other OSes?
 core.sys.windows.unknwn.IUnknown is defined under version(Windows).

    I wonder what the exact compiler hook is.


 Question 2. If this fails, may I emulate COM vtable layout with
 extern(C++) class? I wonder what the exact differences are anyway between
 extern(C++) and the special IUnknown.


 Question 3. It seems I can inherit both from A D object and a COM
 interface. What will be the choosen layout?
Nov 02
prev sibling next sibling parent reply evilrat <evilrat666 gmail.com> writes:
You'd better read some more authorative source since my 
experience is very limited on that matter, but here is some quick 
notes

On Thursday, 2 November 2017 at 14:22:56 UTC, Guillaume Piolat 
wrote:
 Question 1. Is it mandatory to inherit from 
 core.sys.windows.unknwn.IUnknown, or just having an interface 
 named "IUnknown" validate it for being a COM interface?

    If yes, then how am I supposed to use COM interfaces in 
 other OSes? core.sys.windows.unknwn.IUnknown is defined under 
 version(Windows).

    I wonder what the exact compiler hook is.
You can't(or maybe you can but that is not a true COM). COM is Windows tech. It is backed up by OLE or whatever server it is. My guess it will work fine when derive from any extern(Windows) interface(that's right, not class) that has base 3 methods(AddRef, Release, QueryInterface) It is also tied to a Windows registry, since to be able to create COM objects using CoCreateInstance its class factory has to be registered with class id (CLSID), then IIRC, for example in C# creating a COM object instance(using new) makes corresponding lookup by GUID to retrieve CLSID and CoCreateInstance calls that factory to make an object. But you don't have to use COM mechanincs on your COM enabled classes inside your code. Now there can be a problem, say for example you want to make a COM class in D for external usage, most likely you will have to make interface first, then derive a class for actual implementation, because class will add stuff to vtable and break order. (just a guess)
 Question 2. If this fails, may I emulate COM vtable layout with 
 extern(C++) class? I wonder what the exact differences are 
 anyway between extern(C++) and the special IUnknown.
I don't know the exact internals mechanics, but yes, not sure if extern(C++) will work though. COM can be used from C, and so COM methods is basically a C function that takes object as first argument, so on C++ side it is flavored to make a vtable and respective method calls(or vice versa, depending how the specific class implemented). (like I said, find some better read on this) Also since it can be implemented in C, and that requires manually making COM vtable in there(IIRC with an array), you can just do the same in D.
 Question 3. It seems I can inherit both from A D object and a 
 COM interface. What will be the choosen layout?
like I said in Q2, if your goal is to make COM class accessible by other languages then make interface derived from IUnknown(or any other COM interface you like) and fill in the methods, but implement them in derived from that interface class. (again, just a guess, because of vtable shifting) and don't forget, on Windows you also must register a class factory (see IClassFactory.CreateInstance) to be able to create objects from other COM clients.
Nov 02
parent reply Guillaume Piolat <contact spam.com> writes:
On Friday, 3 November 2017 at 02:30:59 UTC, evilrat wrote:
 You can't(or maybe you can but that is not a true COM). COM is 
 Windows tech. It is backed up by OLE or whatever server it is.
What happens is that I translate a SDK which provides "COM-like" objects, on Windows and Mac (claiming ABI compatibility) and I'd like to know if I'll be able to use the COM facilities in D. No class will need registering.
 My guess it will work fine when derive from any extern(Windows) 
 interface(that's right, not class) that has base 3 
 methods(AddRef, Release, QueryInterface)
I'll test that scenario and see if the layout is the same.
Nov 03
parent Guillaume Piolat <contact spam.com> writes:
On Friday, 3 November 2017 at 12:20:43 UTC, Guillaume Piolat 
wrote:
 On Friday, 3 November 2017 at 02:30:59 UTC, evilrat wrote:
 My guess it will work fine when derive from any 
 extern(Windows) interface(that's right, not class) that has 
 base 3 methods(AddRef, Release, QueryInterface)
I'll test that scenario and see if the layout is the same.
And you were right in this.
Nov 03
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
On Thursday, 2 November 2017 at 14:22:56 UTC, Guillaume Piolat 
wrote:
 Question 1. Is it mandatory to inherit from 
 core.sys.windows.unknwn.IUnknown, or just having an interface 
 named "IUnknown" validate it for being a COM interface?

    If yes, then how am I supposed to use COM interfaces in 
 other OSes? core.sys.windows.unknwn.IUnknown is defined under 
 version(Windows).
I suppose you will need a bunch of definitions. One strange thing is that core.sys.windows defines GUID with alignment 1, which I expect to differ on other platforms.
    I wonder what the exact compiler hook is.
I only looks at the name.
 Question 2. If this fails, may I emulate COM vtable layout with 
 extern(C++) class? I wonder what the exact differences are 
 anyway between extern(C++) and the special IUnknown.
Depends on implementation. XPCOM uses straight C++ ABI on linux, so look what you want to work with.
 Question 3. It seems I can inherit both from A D object and a 
 COM interface. What will be the choosen layout?
Shouldn't matter, interface defines ABI, how it's implemented is irrelevant - that's the very idea behind COM. It's actually legal to implement interfaces with composition, the caller still doesn't see anything.
Nov 03
parent reply Guillaume Piolat <contact spam.com> writes:
On Friday, 3 November 2017 at 10:50:27 UTC, Kagamin wrote:
 It only looks at the name.
I'll test if that name needs to be "IUnknown" or the exact "core.sys.windows.unknwn.IUnknown", since I'm in nogc and not necessarily on Windows, so I can't inherit from core.sys.windows.unknwn.IUnknown (but still need a COM-like layout).
Nov 03
parent Guillaume Piolat <contact spam.com> writes:
On Friday, 3 November 2017 at 12:24:43 UTC, Guillaume Piolat 
wrote:
 On Friday, 3 November 2017 at 10:50:27 UTC, Kagamin wrote:
 It only looks at the name.
I'll test if that name needs to be "IUnknown" or the exact "core.sys.windows.unknwn.IUnknown", since I'm in nogc and not necessarily on Windows, so I can't inherit from core.sys.windows.unknwn.IUnknown (but still need a COM-like layout).
The answer is that "IUnknown" is all that is needed, no matter what the fully qualified name.
Nov 03
prev sibling parent Guillaume Piolat <contact spam.com> writes:
Answering my own questions:

On Thursday, 2 November 2017 at 14:22:56 UTC, Guillaume Piolat 
wrote:
 Question 1. Is it mandatory to inherit from 
 core.sys.windows.unknwn.IUnknown, or just having an interface 
 named "IUnknown" validate it for being a COM interface?
Deriving from an interface named "IUnknown", in whatever module, with whatever actual methods, make the compiler consider it a "COM interface", which applies semantic restrictions. The actual layout is _separated_ from the compiler considering it as a "COM interface", and one can achieve the exact desired layout with a IUnknown-like interface named in other way. One can test this with `delete interfaceInstance`. The only layout effect of having the compiler consider it like COM interface, is that derived class will become "COM classes" whose only effects seems to be extern(System) as default linkage type. So: you don't need the compiler to follow COM ABI, it just makes it easier.
 Question 2. If this fails, may I emulate COM vtable layout with 
 extern(C++) class? I wonder what the exact differences are 
 anyway between extern(C++) and the special IUnknown.
extern(C++) is indeed very flexible, with no virtual methods, whereas COM objects will have at least 8. However this doesn't seem needed.
 Question 3. It seems I can inherit both from A D object and a 
 COM interface. What will be the choosen layout?
Should not be a problem. The problem I had was my inability to override a base class methods since I forgot extern(D). This problem is talked about in the spec: https://dlang.org/spec/interface.html#com-interfaces
Nov 03