The March on COM Continues

Motoring along with a COM interop module…

After GUID/UUID, the next thing to deal with is BSTR.  I’m not much of a COM programmer, but there are two things over the years that I’ve always wanted to stay at arms length from.  The first is the BSTR, and the second is the VARIANT.  These things were possibly greatly useful in their day, but these days, they’re just kind of anacronistic.

At any rate, BSTRs are a beastly must, because in the Kinect API, there are BSTRs.  It seems a bit odd to me that given the way the world works today with dynamic languages, we could not come up with easier interfaces, that don’t require the support of a full framework such as COM to do something as asimple as “GetNextFrame”.  But, there you have it.

I have managed to do the code wrangling to get the Nuixxx interfaces from the Microsoft Kinect SDK into “compilable” shape.  That is, I looked at the SDK headers, and transformed them bit by bit into what I thought was correct form for interop with LuaJIT.  I haven’t actually tested them as yet, because the rest of the COM support isn’t quite fixed.  But, soon enough, I might be able to grab frames from the Kinect.

At any rate, the BanateCoreWin32 codebase has taken on quite a lot of new APIs and whatnot.  If you’re interested in looking at such things, you might head on over to the GitHub and browse around.

Along the way, I actually ran into a stumper, and none other than Mike Pall gave me some hints and tips to make things better.  The primary thing I had to deal with was forward declarations of structures.  A common construct such as:

typedef struct AStructure AStructure

typedef struct otherstruct {
AStructure *food;
} otherstruct;

typedef struct AStructure {
otherstruct *areference;
}

The Microsoft COM headers are full of stuff like this, except they use the word “interface” instead of ‘struct’.  In most cases, I could just change the word to ‘struct’, and the rest is fine, and things work out.

While he was at it, Mike pointed out that the construct that I was using:

floatv = ffi.cdef("float[?]")

wasn’t the most efficient thing in the world.  Although it’s convenient when you’re doing more interesting structures than basic types, it’s not particularly performant when dealing with base types such as numbers.  Instead, it’s better to just do:

vec3 = ffi.cdef("float[3]")
vec4 = ffi.cdef("float[4]")

You still can’t assign a metatable, as far as I know, but you get the easy constructor semantics:

vec3(x, y, z)

So, things are humming along.  Having spent a day on the bowels of COM interop, I feel even more strongly that such interfaces need to be left far behind.  There is too much time and energy spent on trying to massage the right things to happen.  In comparison, doing interop to straight C interfaces is almost mind numbingly simple.  Of course, it was great for the time, and solved a lot of problems, but I wonder what would happen if interfaces today were defined in something like Lua, instead of IDL and COM, etc.



Leave a comment