X
Prev    Next

ImageIngester is portable... not really (2006-03-25)

2006-03-25

What seems now like a long time ago (late 1980s/early 1990s) I created a tool (and a company, too) called XVT that provided a way to write portable GUI apps that, once compiled and linked with our library, could run natively on Windows, Macs, OS/2, X/Motif, OpenLook, and even character displays. Looking at this list, you already know what happened: Only the first two are really used now, and hardly any corporate developers (the ones with big bucks to spend on tools) develop for the Mac. It was fun while it lasted, though!

The apps I've built for distribution over the last few years (links at left) fall into three classes:

  1. Web, usable from almost any OS (Mudbag)
  2. Windows-only (Albumatic)
  3. Multi-platform (ImageIngester, CsvTool)

Of course, like many developers, I didn't much care about multi-platform apps (in recent years--I'm not talking about 1990 now) until I started using a Mac, and might not have cared even then if the Mac were as popular as Windows is. So, when I wrote CsvTool (and a few other apps that aren't publicly available), I used Java and Swing. That went OK, but the IDEs are too complicated (I've used JDeveloper, NetBeans, and Eclipse), and hence aren't much fun. I define "fun" as Apple's Xcode/Interface Builder, which started out life as NextStep Developer (I think that's what it was called). That's the gold standard (if you haven't tried it, your gold standard is only bronze, sorry).

So, since these little programs are supposed to be fun projects, there was a disconnect.

I really wanted to use Xcode/Interface Builder for my next project, which turned out to be ImageIngester. I was intrigued by Objective C, too, a language that's never gotten the respect it deserved. Its lineage is even more royal than Xcode/Interface Builder: Objective C is Smalltalk grafted onto C.

I can now report that my experience with Xcode/Interface Builder was even better than I thought it would be, and I'm itching to try something new, just to have an excuse for firing it up again.

OK, so I put ImageIngester on the web for downloads, got some happy users, and got emails from people wanting a Windows version. What did you expect? It's what I expected, anyway.

Hedging my bets, I wrote ImageIngester in two parts.

  1. An engine that does the hard work, written in Standard C with Single-UNIX-Specification-conforming OS calls. (If you don't know what they are, click on the UNIX book link at the right.)
  2. A OS X-only GUI written for Cocoa in Objective C. (Fun!)
The Mac is the only system in the world that lets you combine these two technologies!

My plan was that if I ever needed a Windows version, it would take only a couple of days to write the GUI (ImageIngester doesn't have much of a GUI), and this turned out to be right, because I know Visual Studio, C++, and MFC like the back of my hand and can work very quickly. Visual Studio is pretty good, too. It's not visually as appealing as Interface Builder, and suffers from the fact that C++ has very early binding, whereas Objective C (like Smalltalk) has very late binding. It's happy to call a method that may or may not exist--the object figures out what to do with the message. (My copy of Visual Studio is about 8 years old, so sorry if the 2005 version is fun to use and I don't know it. I doubt it though.)

Getting the engine to run on Windows was the messy part, not fun at all. I thought for 15 min. about getting a toolkit (MKS maybe) to help, then decided that the only problem was my use of nftw and opendir/readdir/closedir, so I just wrote nftw for Windows, and then wrote the dir stuff in terms of nftw. It turned out to be easy enough. Found a few bugs that were on the Mac version, too, as I went through the code on Windows, so the exercise had some side-benefits.

(Note to readers of Advanced UNIX Programming: Since ImageIngester copies original, irreplaceable images, its main copy loop takes a paranoid's view of error checking, carrying the methods in the book to extremes. Someday I may have a blog entry on what the copy loop looks like.)

In the end, writing natively, rather than with Java/Swing, turned out to be fortunate, because I decided to arrange for mount/unmount notifications (so I could tell when the camera/card was connected), and I doubt that Swing can do that. (I may be wrong, as I didn't bother to look--decision already made.)

So, if you look at the ImageIngester site, you'll see two versions, Mac and Windows. They each work better than any Java program ever could and, another advantage, the Windows app doesn't need anything extra, like Java, to be installed. (There are Java launchers that can handle this problem, and I use one for CsvTool, but I think they still create problems for users.)

What I really wanted to do was just write the Mac app, darn it! Maybe next time...