Class info on interfaces

rumbu via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Aug 28 13:40:59 PDT 2015


On Friday, 28 August 2015 at 19:36:37 UTC, Jacob Carlborg wrote:
> On 2015-08-28 17:41, rumbu wrote:
>
>> I don't know about Objective-C, but:
>>
>> - for native D interfaces __traits(getVirtualIndex,
>> NativeInterface.firstFunction) == 1 since the first entry in 
>> vtbl is the
>> contained object
>> - for C++ interfaces __traits(getVirtualIndex,
>> CPPInterface.firstFunction) == 0
>> - COM interfaces: __traits(getVirtualIndex, 
>> CPPInterface.firstFunction)
>> == 0 and inherit IUnknown
>
> I'm wondering how reliable that is. Might be better to check 
> the linkage of a method in the interface as Adam suggested.

The linkage check it's good as long you don't have an abomination 
like this:

extern(C++) interface CPPInterface
{
     extern(D) void foo();
}

Anyway, the problem is the availability of such function. If the 
interface doesn't contain any function, there is no way to detect 
the type, except for COM Interfaces which are clearly 
implementing IUnknown.

But deriving a new interface and defining a sentinel function, it 
works:

import std.stdio;
import std.traits;
import core.sys.windows.com;

interface NativeInterface {}

interface COMInterface : IUnknown {}

extern(C++) interface CPPInterface {}

enum InterfaceKind { native, windows, cpp }

template interfaceKind(I) if (is(I == interface))
{
     interface J : I { void __foo__(); }
     static if (functionLinkage!(J.__foo__) == "D")
         enum interfaceKind = InterfaceKind.native;
     else static if (functionLinkage!(J.__foo__) == "Windows")
         enum interfaceKind = InterfaceKind.windows;
     else static if (functionLinkage!(J.__foo__) == "C++")
         enum interfaceKind = InterfaceKind.cpp;
     else static assert(false, "Unknown interface kind.");
}

int main(string[] argv)
{
    static assert(interfaceKind!NativeInterface == 
InterfaceKind.native);
    static assert(interfaceKind!COMInterface == 
InterfaceKind.windows);
    static assert(interfaceKind!CPPInterface == InterfaceKind.cpp);
    return 0;
}







More information about the Digitalmars-d-learn mailing list