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;
}





Reply via email to