Dynamic binding to the Mono runtime API

Adam Wilson via Digitalmars-d-announce digitalmars-d-announce at puremagic.com
Sun Jun 4 02:43:23 PDT 2017


On 6/4/17 01:18, Jakub Szewczyk wrote:
> This is an interface to the Mono libraries, D/CLI would require quite a
> lot of compiler changes, both on the front-end and back-end side, but
> thanks to metaprogramming a wrapper library can get very close to such
> an interface.
> I plan on making an automated D to Mono bridge, akin to LuaD, so that it
> can be used as a scripting platform for e.g. games. I haven't thought
> about doing it the other way around, but now it seems like a very
> interesting idea! Unfortunately no XAML
> (http://www.mono-project.com/docs/gui/wpf/), but many other libraries,
> such as XWT (https://github.com/mono/xwt) could be ported this way, I'll
> certainly look into it.
>
My interest is less in code ports than bindings to the actual code. My 
experience with code ports or translations is that often subtle bugs 
creep in during translation due to the fact that each language has 
different idioms.

What I am thinking about is a tool that loads an assembly, examines it's 
types and methods via this API and emits D code that directly interfaces 
into the .NET types via this API. The tricky part here is mapping the 
.NET dependencies into D. The moment the library exposes a type from a 
dependency, that dependency ALSO needs to be included somehow. All 
libraries reference "mscorlib", AKA the BCL, so we'd have to provide a 
"mono-bcl" package on DUB.

One solution is to simply include the exposed dependency in the 
generated code. This would work because while the D code would have 
distinct types for the same class, the underlying .NET types is the 
same. The drawback with this approach is that you can't share the 
instances across D interfaces as the types are different. For example, 
Library1.B and Library2.C both rely on Dependency.A. In D you would have 
Library1.B.A and Library2.C.A and these two types, while the same in 
practice, are different types to the compiler. Maybe a clever use of 
alias can solve this at code-gen time... more research is required there.

The other solution is too have the code-gen throw an error when it 
encounters a type from a dependency. This ensures that the types are the 
same across libraries in D, but at the cost of increased complexity for 
the developer when running the tool (specifying extra deps) and when 
building their code (ensuring all relevant packages are built/referenced).

I'm not sold on either one. And it'd be best if it's possible to support 
both somehow.

As for the WPF remark, my brain immediately jump to trying to interface 
to .NET/Core using a similar mechanism, but alas some research time 
indicates that this is not possible outside of COM. *le sigh* My 
apologize for the random side-track.

> Mono actually supports some kind of GC bridging as far as I understand,
> as there is a sgen-bridge.h header just for that, and it has apparently
> been used in the C#-Java Xamarin interace on Android. As for exceptions
> - D functions have to be wrapped in a nothrow wrapper, but that can be
> completely automated with templates. The other way around is also quite
> simple - when invoking a Mono function a pointer can be given that will
> set an exception reference if one is thrown from the .NET side, and a
> wrapper can easily rethrow it back to D.
>
On the GC side I was mostly thinking about GC Handles so that the 
objects don't get collected out from underneath us. That is something is 
trivial to code-gen.

As for exceptions, I like the catch->translate->rethrow mechanism. And 
if the exception is unknown we could simply throw a generic exception. 
The important thing is to get close to the D experience, not try to map 
it perfectly.

> I can make a static library version, it's just some regex substitutions
> done on the functions file actually, most probably I'll publish it
> today. It will be a dub subconfiguration like it is the case for GLFW3.
> Btw, I've manually ported the basic and configuration headers, so that
> no mistakes are made, and then used DStep and a modified DStep to
> generate the rest of the headers - my modification was only to change
> the way function declarations are generated, to make them in derelict
> form of alias da_function = void function(...);, and the rest was done
> with quite a lot of editor(VSCode) shortcuts.

Thank you for this! I find static libraries easier to deal with. I'm 
sure other people have differing opinions, so having both would make 
everyone happy.

I am very excited about this!

-- 
Adam Wilson
IRC: LightBender
import quiet.dlang.dev;


More information about the Digitalmars-d-announce mailing list