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