DotNET.jl:连接 Julia 与 .NET 生态的桥梁


#1

新年快乐,送上新包

Julia 有很多强大的 FFI,可以使用其他语言和环境的代码,比如 PyCallCxxRCall。作为多年的 Windows 用户,我从刚接触 Julia 开始就一直希望能在这个语言里用上 .NET,这样能够大幅提升与微软生态的互操作性(GUI、Office 套件等)。

虽然 .NET 因为长期与 Windows 捆绑在一起,市场占有率比较低,但是不得不承认它也是一个很优秀的托管语言框架。伴随着微软对于开源的态度转变,.NET 也开始了跨平台的演进。一边是新兴的高性能计算语言,一边是商业级的应用开发平台,将两者结合在一起应该是有明显收益的。也许是因为圈子重合度比较低,Julia 的用户里很少有熟悉微软生态的开发者在做这方面的事情,很多事情也停滞不前。比如:

https://discourse.julialang.org/t/is-it-possible-to-call-c-functions-with-julia/18979
有人希望直接在 Julia 里调用 C# 写的函数,最后得出的结论是要么让 .NET 导出 C API,要么通过 Python 的 C# FFI 来间接实现。

https://github.com/JuliaLang/julia/issues/16565
https://github.com/JuliaLang/julia/pull/11478
因为 Windows 的默认 shell cmd.exe 实在不堪大用,有人希望能把 REPL 的 shell 模式替换为更加现代的 PowerShell,但苦于没有跨越托管语言边界的交互手段,于是有人建议使用 MSVC 编写托管 C++(C++/CLI)来做中间层,或者用纯 C# 去操作 PowerShell 然后把 C API 暴露给 Julia。

https://discourse.juliacn.com/t/topic/2060
中文社区这边也有直接需求。当时我给的 ad-hoc 的解决方案就是走 IPC:https://discourse.juliacn.com/t/topic/2687

如果 Julia 有了 .NET 的 FFI,上述问题就不再是问题。既然一直没人做这件事,那我就开个好头吧 : )

项目地址:https://github.com/azurefx/DotNET.jl

经过两周的开发,目前虽然还处于实验性阶段,但是已经具有使用价值了。等待包注册完成后会发布第一个版本。

比如,尝试在 Julia 里启动 PowerShell 环境:

using DotNET
Assembly = T"System.Reflection.Assembly";
Assembly.LoadFrom(raw"C:\Program Files\PowerShell\6\System.Management.Automation.dll");
PowerShell = T"System.Management.Automation.PowerShell,System.Management.Automation";
ps = PowerShell.Create();
files = ps.AddScript("Get-ChildItem").Invoke[]();
collect(files)
10-element Array{CLRObject,1}:
 System.Management.Automation.PSObject("C:\\Users\\Azure\\Documents\\Git\\DotNET.jl\\deps")
 System.Management.Automation.PSObject("C:\\Users\\Azure\\Documents\\Git\\DotNET.jl\\src")
 System.Management.Automation.PSObject("C:\\Users\\Azure\\Documents\\Git\\DotNET.jl\\test")
 System.Management.Automation.PSObject("C:\\Users\\Azure\\Documents\\Git\\DotNET.jl\\.gitignore")
 System.Management.Automation.PSObject("C:\\Users\\Azure\\Documents\\Git\\DotNET.jl\\.travis.yml")
 System.Management.Automation.PSObject("C:\\Users\\Azure\\Documents\\Git\\DotNET.jl\\Artifacts.toml")
 System.Management.Automation.PSObject("C:\\Users\\Azure\\Documents\\Git\\DotNET.jl\\LICENSE")
 System.Management.Automation.PSObject("C:\\Users\\Azure\\Documents\\Git\\DotNET.jl\\Manifest.toml")
 System.Management.Automation.PSObject("C:\\Users\\Azure\\Documents\\Git\\DotNET.jl\\Project.toml")
 System.Management.Automation.PSObject("C:\\Users\\Azure\\Documents\\Git\\DotNET.jl\\README.md")

有了 FFI 之后,我们就会发现,之前难以实现的东西就突然变得很平凡了。比如,做一些跨平台的 .NET GUI 库(Avalon)的 wrapper、用 PowerShell 增强 shell 模式的能力,甚至借助 .NET 完善的编译器工具链在 Julia 里直接内嵌 C# 代码。

想起 Julia 首页底部的一段话:

Julia 已经被下载超过两百万次。Julia 的社区开发了一千九百多外部库。这些包括各种数学库,数据处理工具,以及通用计算库等。除此之外,您还可以很容易地调用 Python, R, C/Fortran, C++, 和 Java 等的外部库. 如果您找不到需要的,可以在 Julia 中文社区 询问, 自己贡献更好!

很荣幸为其添上一笔,希望 Julia 的工具箱越来越强大。


#2

如果能写个blog post就更好了,可以写完发在投稿的那个下面