Thread overview
TypeInfo_Interface from runtime string?
Jun 22, 2016
Thalamus
Jun 22, 2016
Basile B.
Jun 22, 2016
Thalamus
Jun 22, 2016
Thalamus
June 22, 2016
Hi everyone,

My project includes lots of .Net interop via C linkage. One of the things I need to do is refer in C# to an interface declared in the D code, and then to actually work with the interface concretely in the D layer. So, I need to get a TypeInfo_Interface object from a string passed in from C#.

The problem isn't in marshaling the string between C# and D, but rather what to do with the string once I have it in D.

So in the D code, where interfaceName is the fully qualified name of an interface, e.g.  "MyPackage.MyModule.MyInterface", what I would like is something like:


TypeInfo_Interface theInterface = new TypeInfo_Interface(interfaceName);


But there's no such constructor.

Apologies if this seems like it should be obvious, but I couldn't find anything in the forums or the wider web. :)

thanks,
Thalamus

June 22, 2016
On Wednesday, 22 June 2016 at 15:15:51 UTC, Thalamus wrote:
> Hi everyone,
>
> My project includes lots of .Net interop via C linkage. One of the things I need to do is refer in C# to an interface declared in the D code, and then to actually work with the interface concretely in the D layer. So, I need to get a TypeInfo_Interface object from a string passed in from C#.
>
> The problem isn't in marshaling the string between C# and D, but rather what to do with the string once I have it in D.
>
> So in the D code, where interfaceName is the fully qualified name of an interface, e.g.  "MyPackage.MyModule.MyInterface", what I would like is something like:
>
>
> TypeInfo_Interface theInterface = new TypeInfo_Interface(interfaceName);
>
>
> But there's no such constructor.

No need for a constructor. typeid() returns a static instance that's pre-allocated.

> Apologies if this seems like it should be obvious, but I couldn't find anything in the forums or the wider web. :)

No problem. What you need to do is to create a registry with all the possible TypeInfo_Interfaces. This registry will have the form of an associative array. Each TypeInfo_Interface will be selectable with the fully qualified string, for example:

    __gshared TypeInfo_Interface[string] registry;

    interface Foo{}
    interface Bar{}

    static this()
    {
        registry[typeid(Foo).toString] = typeid(Foo);
        registry[typeid(Bar).toString] = typeid(Bar);
    }

That's the basic idea but with introspection (foreach(member; traits....) you should be able to automate the creation of the registry, in a smarter way.
June 22, 2016
On Wednesday, 22 June 2016 at 15:43:08 UTC, Basile B. wrote:
> On Wednesday, 22 June 2016 at 15:15:51 UTC, Thalamus wrote:
>> [...]
>
> No need for a constructor. typeid() returns a static instance that's pre-allocated.
>
> [...]

Thanks Basile.
June 22, 2016
On Wednesday, 22 June 2016 at 15:46:15 UTC, Thalamus wrote:
> On Wednesday, 22 June 2016 at 15:43:08 UTC, Basile B. wrote:
>> On Wednesday, 22 June 2016 at 15:15:51 UTC, Thalamus wrote:
>>> [...]
>>
>> No need for a constructor. typeid() returns a static instance that's pre-allocated.
>>
>> [...]
>
> Thanks Basile.

Hit Send too soon...

Thanks Basile. As it turned out I was already doing something very similar for mapping types to interfaces and to other types, using shared static constructors to perform registration into associative arrays, e.g.

TypeInfo_Class[TypeInfo_Class]
     and
TypeInfo_Interface[TypeInfo_Class]

So I can easily add

TypeInfo_Interface[string]
     and
TypeInfo_Class[string]

as part of the existing registration process and then expose a simple lookup method. Thanks for the good idea! :)