Hydra update: importing interfaces

It sounds like Hydra documentation will be forthcoming in a month or so (they shipped Hydra 3 last month, and they said they didn’t think the docs were worth delaying two months for, so the math works out to about a month left). In the meantime, importing interfaces using Hydra turns out to be easy.

In Delphi, there’s a “Hydra” menu in the menu bar (who’da thunk it?), and one of the menu items lets you browse to a .NET assembly and select which interfaces you want to import, at which point it creates a Win32 unit for you. If you do it again, it replaces the unit it generated the first time, which is good.

The IDE menu item is kind of nice to have, although I’d also want a command-line tool that I can tie into a rakefile or something, so I know the two sides don’t ever get out of sync. I’ve posted to their newsgroups asking if they have such a thing. If they don’t, I’ll probably bug them to write one. (grin)

Your .NET interface must descend from IHYCrossPlatformInterface, and must have a Guid attribute; otherwise the tool won’t import it. String return types seem to translate quite nicely, and I assume they work; they look about right. There are rumors that you can marshal complicated types like records if you write the MarshalAs stuff yourself; I’m not sure how that works.

There’s also a similar menu item in Visual Studio, which will read Delphi code and generate a corresponding .NET interface. I haven’t tried it yet, but it’s in the Tools > Hydra submenu.

The various ways to call from Win32 into .NET

We’ve got several major applications written in Delphi, and several newer projects written in C#. And they need to talk to each other.

There are several ways for unmanaged Win32 code to talk to managed .NET code, and we currently use, or have used, most of them:

  • We have a couple of C# Windows services that run TCP/IP servers, and Delphi clients that connect to them.
  • We have a C# application that reads from Console.Input and writes to Console.Output, and a Delphi application that launches it and assigns pipes for its standard input and output handles. (If you’re thinking of doing this, see Console out from a non-console app for an interesting bit of info.)
  • At one point, we had a .NET assembly that registered some of its objects as COM objects, and a Delphi DLL that imported and used those type libraries. We do not do this anymore. To say that versioning is a bloody screaming nightmare doesn’t really do it justice. (Just try getting two different versions of the same app installed on a QA or client-support machine at the same time, when COM object registrations are machine-global.)
  • We have a C++ DLL that has unmanaged exports and instantiates managed objects inside unmanaged C++ class wrappers, and then exposes them via flat DLL exports. Sam has blogged about this already. It’s painful to marshal anything but the simplest of types, and you need to be a COM guru just to figure out who’s responsible for freeing strings, but it’s doable. (You can also do Delphi for .NET libraries with unmanaged exports; it’s pretty much the same thing.)

I recently stumbled across another option: RemObjects Hydra. Hydra was originally a plug-in framework for Delphi/Win32. But as of Hydra 3, which was released about a month ago, you can write the host app in either Win32 or .NET, and you can write the plug-in in either Win32 or .NET. So basically, you get total interop, without needing to do anything very ugly to get it. Sounds good so far!

What looks really cool (though I haven’t tried it yet) is that you can write a GUI frame in Delphi, and embed it into a .NET GUI; or vice versa, writing a UserControl in .NET and embedding it into a Win32 GUI. That’s not something you could do with just C++ glue. Without Hydra, that would probably take (shudder) COM. They even claim to have something that will let you use VCL TActions in a .NET app.

Hydra works by passing interfaces back and forth between Win32 and .NET. They’ve got a tool that will parse Delphi code and generate the corresponding .NET interface, and they’ve got something that will read .NET metadata and generate the corresponding Delphi interface, and make them compatible so you can just pass the interfaces back and forth and it all works.

That’s the idea, anyway. I haven’t used either of these translation tools. I haven’t even found them yet, because they don’t bother to document them.

They don’t bother to document much of anything. They’ve got an article on their Web site that talks in general about Hydra’s features, and another that shows how to use Hydra to embed simple GUI frames, but nothing about actually doing interesting work by calling actual functions with actual parameters. They do have a handful of samples in the download, but there’s one I can’t even open because I haven’t purchased all the third-party Delphi controls it requires, and I haven’t found any yet that use custom interfaces.

What I’ve seen does work, mind you, and it’s a far sight nicer than C++ glue. I’ve already had a chance to figure out a lot of the gotchas (like the crash on exit with a nice, friendly “Interface cast not supported” if you free things in the wrong order). However, what I’ve actually used is only a small part of what Hydra says it can do, and I don’t know if it’s enough to justify the $500-per-seat entry fee.


I’ve written a coroutine library for C#, which I intend to use in my video game. (I plan to open-source it in the future, after I’ve filed the necessary paperwork with my employer.)

So what’s a coroutine?

I’ve seen several conflicting definitions. In my implementation at least, a coroutine is a method that can yield.

Sounds a lot like C# 2.0’s iterators, doesn’t it? The difference is that C# iterators are restricted to being a single method; the “yield return”(s) must occur inside that method. You can’t do an Extract Method on a chunk of code that includes a “yield return”. (And because of the way they’re implemented — with a codegenned state machine — this limitation is probably permanent. The stack issues are too messy to deal with this way.)

With coroutines, the yield can be extracted into another method. You can even use recursion. Each coroutine has its own call stack, so you can do pretty much whatever you want. When you call the Yield() method, you’re instantly zapped all the way back to whoever originally called into the coroutine. The next time someone calls into the coroutine, you’re zapped back to wherever you were when you yielded, call stack and all.

What are they good for?

In my game, I’m going to have something like this:

Actor bob = new Actor("bob.png");
Coroutines.Add(new Coroutine(delegate {

This will put a guy on the screen who walks in circles. (Okay, squares.) The various Walk() methods will be implemented something like this (pseudocode):

    move the sprite on the screen
until we've moved the requisite distance

The program’s main work happens in the Paint event of the main user control. Once I implement coroutines, Paint will loop through all the registered coroutines, executing each one until it yields, then moving on to the next coroutine in the list. It’s really just cooperative multitasking. All the animation — wandering NPCs, flickering torches, etc. — will be, if all goes well, handled by coroutines. Which means, it’ll be a piece of cake to add a new piece of animation.

I’ll even be able to use coroutines to implement the main user-input loop, something like this:

Coroutines.Add(new Coroutine(delegate {
    if (IsKeyPressed(Keys.Up))
    else if (IsKeyPressed(Keys.Down))
    else if (IsKeyPressed(Keys.Left))
    else if (IsKeyPressed(Keys.Right))

If I can swing it, I’ll even do cutscenes as coroutines. When it comes time to do a pre-scripted scene, I’ll plug in a “cutscene” coroutine, at which point the Paint event will run only the cutscene, ignoring all the other coroutines until the cutscene is done. So all the action freezes in its tracks, except what’s specified in the cutscene script:

PlayCutscene(new Coroutine(delegate {
    Hero.Say("You'll never get away with this, Bad Guy!");
    BadGuy.Say("You fools think you can stop me? Taste my magic!");

How are they implemented?

I originally, a couple of years ago, was thinking about using fibers to implement coroutines. (A fiber is much like a thread, with its own call stack and everything. The difference is in scheduling. Threads are preemptively scheduled by the OS, and all appear to be running at the same time. Fibers are manually scheduled by your app, so you decide exactly when they run and when they stop. See Raymond Chen’s posts, “Using fibers to simplify enumerators [Part 1] [Part 2] [Part 3]”.)

Fibers are ideal for coroutines. When you want to call the coroutine, you just swap in a different fiber (with its own call stack, thus putting you right back where you were when you yielded), and when you want to yield, you swap in the original fiber (and its call stack, thus putting you right back at the caller).

The downside is that your runtime library (the C runtime, or the .NET runtime, or whatever) needs to be fully fiber-aware. Most aren’t. There’s a lot of potential problems lurking here (see Raymond Chen’s dire warnings about fibers). The .NET runtime was not fiber-aware, at least a couple of years ago when I e-mailed some of the developers. (It might be more so now — I think MS SQL Server uses fibers internally, and it can host the CLR — but I wouldn’t want to count on it working in a normal .NET app, without MSSQL’s specially-tuned CLR host.)

So I cheat. I use threads, but I only let one of them run at a time. When I create a coroutine, I create a thread, and then do some handshaking that ends with a call to Monitor.Wait(), which blocks the coroutine thread — it won’t run anymore until it’s unblocked. When it’s time to call into the coroutine, I do a handoff that ends with the calling thread blocked, and the coroutine thread runnable. Same kind of handoff on the way back.

Those handoffs are kind of expensive, compared with other implementations. If you need speed, you’ll want to write your own state machine, and avoid all this context switching. (Or you’ll want to use a fiber-aware runtime — switching fibers is pretty cheap.) But if you want expressive code, I think coroutines hold some promise.