Hacker News new | ask | show | jobs
by wahern 1046 days ago
Almost. You could start the main loop ([NSApp run]), but the reverse bridge would need to be implemented as the 'run' method blocks so you need event callbacks to be able execute any Lua code within the main loop. And for event callbacks you basically need the ability to create C Blocks (Apple's bespoke C/C++ closure primitive) to forward calls into Lua, and I just haven't done that yet. (It's simple in principle.)

I originally had no inkling that Objective-C was so easy to write bindings for. I was vaguely familiar with its message passing architecture, but didn't appreciate the low-level implications--the potential ABI power (not just API) that came from foregoing static linking. I started my app hoping to not have to write many bindings to macOS interfaces, partly because I wanted to port it to Windows and Linux. I'm using the Yue GUI toolkit, which made it easy to bring up a simple Lua app without having to understand anything about platform GUI frameworks.[1] I wrote a whole slew of Core Foundation (plain C) Lua bindings for little things like property file integration, hoping to avoid dealing with Cocoa APIs. But eventually all the little limitations of Yue (many now resolved) and my need for deeper desktop integration forced my hand.[2]

My Lua bridge is definitely not the first, but most (all?) such projects are dead or dormant. Some might still be usable with some tweaking; I don't think out-of-the-box, though, which IIRC helped push me toward writing my own. My app is currently closed source. I've open source'd parts of it already (e.g. early version of a suite of LPeg parsers for X.509-based formats, posted to the Lua mailing list), but my Lua/Objective-C bridge is spread across several files (e.g. the objc_msgSend thunk permutation and code generator) and not something that can be easily dumped into a standalone form without a little refactoring. If I have the opportunity to do so, I may in the future. I just don't like publicly releasing anything that isn't usable out of the box. But if you contact me by e-mail I'd be happy to share the code: william@25thandClement.com or william@keymux.com.

[1] Yue also has JavaScript bindings, and both sets of bindings rely on a shared C++ framework, so Yue provides equal treatment to C++, JavaScript, and Lua applications.

[2] My app, KeyMux, is for integrating common open source toolchains and work flows with hardware-protected RSA and ECC keys, including the Apple T2 Secure Enclave, for which I had to write static C bindings to Apple's Security framework, the low-level public interfaces to which are straight C interfaces. So in truth I would have had to write Core Foundation bindings one way or another as Security heavily uses CFArray, CFDictionary, CFNumber, and CFString. But those bindings probably would have been much simpler and more basic if I knew I would be able to lean on the Objective-C frameworks (e.g. Foundation, AppKit) for other desktop integration tasks. All of this--the whole world of desktop GUI programming, not just Objective-C--was new territory for me, so at least I picked up a wealth of knowledge on my circuitous journey.

1 comments

Thanks for the detailed explanation and the contact offer <3