Remix.run Logo
bri3d 3 days ago

This is quite interesting: it's easy to blame the use of LLM to find the interface, but really this is a matter of needing to understand the COM calling conventions in order to interact with it.

I found the interface and a C++ sample in about two minutes of GitHub searching:

https://github.com/microsoft/SampleNativeCOMAddin/blob/5512e...

https://github.com/microsoft/SampleNativeCOMAddin/blob/5512e...

but I don't actually think this would have helped the Rust implementation; the authors already knew they wanted a BSTR and a BSTR*, they just didn't understand the COM conventions for BSTR ownership.

vintagedave 2 days ago | parent | next [-]

Every time I read an article on someone understanding COM from interfaces and dispatching, I think: reinventing Delphi, badly.

antonvs 2 days ago | parent | next [-]

COM is cross-language, though, and cross-process, and even cross-machine although not often used that way these days.

Life is definitely easier if you can restrict everything to being in the same language.

vintagedave 2 days ago | parent [-]

Delphi was designed to be COM-compatible, so the vtable layout was compatible, for example. Its interfaces, via the inbuilt interface keyword, use COM-compatible reference counting. It has inbuilt RTL types for handling a lot of common COM scenarios. It did this back in the 90s and remains extremely useful for COM still today.

Then late 2010s, C++Builder (its sister product) dropped ATL to DAX -- Delphi ActiveX aka COM -- and using COM from C++ uses the same inbuilt support, including keyword suggestions and RTL types. It's not quite as clean since it uses language bridging to do so, but it's still a lot nicer than normal C++ and COM.

Seeing someone do COM from first principles in 2025 is jarring.

pjmlp a day ago | parent | next [-]

You mean, like Microsoft themselves?

.NET COM support was never as nice, with the RCW/CCW layer, now they have redoned it for modern .NET Core, still you need some knowledge how to use it from C++ to fully master it.

Then there is CsWinRT, which is supposed to be the runtime portion of .NET Native, which to this day has enough bugs and not as easy to use as it was .NET Native.

Finally, on the C++ side it has been a wasteland of frameworks, since MFC there have been multiple attempts, and when they finally had something close to C++ Builder with C++/CX, an internal team managed to sell to their managers the idea to kill C++/CX and replace it with C++/WinRT.

Nowadays C++/WinRT is sold as the way to do COM and WinRT, it is actually in maintenance, stuck in C++17, those folks moved on to the windows-rs project mentioned on the article, and the usuability story sucks.

Editing IDL files without any kind of code completion or syntax highlighting, non-existing tooling since COM was introduced, manually merging the generated C++ code into the ongoing project.

To complement your last sentence, seeing Microsoft employees push COM from first principles in 2025 is jarring.

antonvs 2 days ago | parent | prev [-]

Oh I see. Python, Ruby, and various other high level languages, including of course the MS languages, have pretty seamless integration as well, although not at the level of direct binary compatibility. I imagine they just use wrappers.

pjmlp a day ago | parent [-]

Not C++, it has been a battlefield of frameworks, each reboot with its own set of sharp edges.

throwup238 2 days ago | parent | prev [-]

I feel that way about most of frontend development since I was a teenager playing with Delphi 7.

bigstrat2003 3 days ago | parent | prev [-]

> it's easy to blame the use of LLM to find the interface, but really this is a matter of needing to understand the COM calling conventions in order to interact with it.

Sure, but I think that this perfectly illustrates why LLMs are not good at programming (and may well never get good): they don't actually understand anything. An LLM is fundamentally incapable of going "this is COM so let me make sure that the function signature matches the calling conventions", it just generates something based on the code it has seen before.

I don't blame the authors for reaching for an LLM given that Microsoft has removed the C++ example code (seriously, what's up with that nonsense?). But it does very nicely highlight why LLMs are such a bad tool.

omneity 2 days ago | parent | next [-]

You might actually get that desired behavior through reasoning, or if the model was reinforced for coding workflows involving COM, or at least enough stack diversity for the model to encounter the need to develop this capability.

In the case of LLMs with reasoning, they might pull this off because reasoning is in fact a search in the direction of extra considerations that improve its performance on the task. This is measured by the verifier during reasoning training, which the LLM learns to emulate during inference hence improved performance.

As for RL coding training, the difference can be slightly blurry since reasoning is also done with RL, but for coding models specifically they also discover additional considerations, or even recipes, through self play against a code execution environment. If that environment includes COM and the training data has COM-related tasks, then the process has a chance to discover the behavior you described and reinforce it during training increasing its likelihood during actual coding.

LLMs are not really just autocomplete engines. Perhaps the first few layers or for base models can be seen as such, but as you introduce instruct and reinforcement tuning LLMs build progressively higher levels of conceptual abstractions from words to sentences to tasks like CNNs learn basic geometric features then composing those into face parts and so on.

piker 3 days ago | parent | prev [-]

In defense of the LLM here: learning COM from scratch given its lack of accessible documentation would have forced us to reach for C# for this minor project.

The LLM gave us an initial boost of productivity and (false) confidence that enabled us to get at the problem with Rust. While the LLM's output was flawed, using it did actually cause us to learn a lot about COM by allowing us to even getting started. That somewhat flies in the face of a lot of the "tech debt" criticisms levied at LLMs (including by me). Yes, we accumulated a bit of debt while working on the project, but were in this case able to pay it off before shipping and it gave us the leverage we needed to approach this problem using pure Rust.