SomeRanDev/reflaxe.CSharp

Auto extern system from C# dlls

SomeRanDev opened this issue ยท 7 comments

Not a requirement, but a lot of people would probably expect eventually.

Seem like Haxe currently uses a custom ocaml lib, seems like a huge undertaking???
https://github.com/HaxeFoundation/ocamllibs/tree/master/ilib

From what I can tell, reading the dlls are pretty easy in C#, wonder if there's anyway to just call a C# program from Haxe macro context to handle everything? Just write C# program that outputs the C# classes info as JSON data, compile for every platform and package it in haxelib? If really wanted to get fancy, implement is as C dll and find way to use that? Hmmmmm

(Before I lose it again, implementation in Haxe's OCaml
https://github.com/HaxeFoundation/haxe/blob/4d9bd89703635716b663fdaaa8557dbe7159f98e/src/codegen/dotnet.ml#L1131)

Extracting types from DLL assemblies can indeed be done fairly easily with a C# program. We can use the open source Mono.Cecil library for that.

Running that C# program from Reflaxe to extract data could make sense indeed. Yes, it would mean starting a new process from the macro context to run the program, but the assemblies data could be cached anyway so it's not like it would be a huge performance hit in practice for subsequent builds.

It could output JSON as you mentioned, giving full control over how to output the externs from the Reflaxe macro context.

Another option (that has its pros and cons) could also to have a completely separate lib that just does this **DLL to C# externs" things, so that we can simply use the generated externs like any other, and the only thing the C# target would care about would be to have those externs somewhere in the classpath

Simn commented

I wouldn't generate externs for this target, it's a step that should be unnecessary, and it shouldn't even be faster because parsing text files is generally slower than reading binaries. Plus, at some point somebody has to update them. Plus, it's difficult to manage different versions that way.

A dependency on an external tool is not without its problems either. Even if our process API wasn't crap, it requires additional setup and moves us further away from a "just -lib this and you're good" state, which would be ideal.

I hear your points and can see how attractive the idea of simply adding a dll reference to the hxml is, but there are situations, like when targeting Unity, where knowing which binary to link with is actually a mess:

If you want to link with some unity assembly, you can't really use --net-lib someAssembly.dll and be done with it because the location of that assembly will vary depending on the Unity version you have, but even worse, if you want to link with some additional Unity module (like InputSystem), the assembly might not even exist or might be some cached thing in a generated folder of your Unity project etc...

In those situations, you are better off having some ready to use externs available that you include in your Haxe project, then export the C# files and give all that to Unity so that it deals with the building and linking.

Having a tool that generates actual C# externs from an assembly DLL, even if that generation needs to be run manually, would be much more convenient for that kind of use case.

There's no reason both couldn't happen. The hard part is having the C# dlls be converted to a Haxe-readable format, but from there, generating .hx extern files OR automatic compile-time externs (supplying Haxe.onTypeNotFound with C# classes?) should both be pretty easy to do. I'll see if I can make a way for both to be options.

Although probably challenging to implement, having both options sounds like the best approach to pursue indeed ๐Ÿ‘

Simn commented

It shouldn't be particularly difficult because all you need after translating the data to Haxe structures is a printer.