A week of debugging

April 14th, 2009

I hate to admit it, but I have been trying to debug one single, annoying bug in my TWAIN plugin for the last week (well, almost). And the worst part about it: it wasn’t even my code that was the root cause! I’m going to go on a bit of a rant, so forgive me if I’m a bit rough with my words, but I am quite displeased at this entire situation.

TWAIN, for those who don’t know, is an interface that allows all kinds of image and audio capture devices to communicate with applications in a standardized way. For developers, this is great because application developers only need to implement one protocol to provide for a wide array of devices, and device manufacturers that provide TWAIN data sources (drivers) automatically support a wide array of applications. Win/win.

There’s a few problems, though. The technical expertise needed to leverage TWAIN is fairly high compared to other popular APIs. Also, the documentation, while mostly correct in the information it provides, does have some typographical and formatting issues that really make it difficult to use. But that’s not what has been causing me so much grief. Oh, no. This problem is much more insidious.

So after figuring out how TWAIN actually works, like how to pass messages and whatnot, I ported the TWAIN header file to pure REALbasic code and proceeded to cook up an example that would show the scanner’s interface dialog. I had been reading through the documentation, and they had mentioned there was a way to receive messages back through a callback, which was optional on Windows, but required for Macs. I quickly decided this would be a good idea, as it would keep most of my code cross-platform, and soft-linked to TWAINDSM.DLL instead of TWAIN_32.DLL.

This process went relatively fast, as there’s only a handful of messages that need to be sent to initialize TWAIN to the point of being useful. I set up the aforementioned callback to beep when it received a useful event. However, when I ran my debug builds, every time the data source’s dialog box would show up just fine and seem mostly functional, but would never fire the callback. And when this callback is responsible for handling closing off the data source dialog, and to start the scanning procedure, you should be able to see how this may be somewhat of a problem.

Because I did notice some problems with how the controls were working, I decided to explore the possibility that I was not handling some sort of event correctly, or REALbasic was causing some issues by not dispatching messages to the window at all. I ended up setting up a GetMsgProc hook (which sees EVERYTHING that passes through the GetMessage() and PeekMessage() functions), but lacking an easy to navigate table of Windows messages, this was like picking a needle out of a haystack. I downloaded Winspector (which is a pretty useful program) to assist in this endeavour, but it did not solve my problem; I was just not seeing the messages I should have seen being sent and received.

So why wasn’t I seeing those messages? Because they weren’t actually being sent and received? Yeah, that should have been a tip-off right there, and saved me two days in debugging time. But no. Because I was using hooks to intercept messages from RB and pass them off to TWAIN, I figured RB might be doing the same thing, and killing any of the events it didn’t recognize before I got a chance to look at them. As a result, I squished my code into a REALbasic plugin and tried to work some wizardry there, but it was to no avail. The messages just weren’t coming or going.

At this point, five days had gone by with this one miserable dialog box misbehaving. And then it dawned on me. The messages weren’t coming or going, period. And the only remaining reason I could think of was because the library I was using was defective. Thankfully I still had the GetMsgProc filter set up, so switching from TWAINDSM.DLL back to TWAIN_32.DLL was no hardship at all. Once I made the switch, everything worked great.

With that nasty bug out of the way, let’s hope my plugin development goes a bit smoother.

In theory, I could just develop the TWAIN stuff in pure RB, but I think I’ll hold off on it for now, as the TWAIN_32.DLL library does not export any of its symbols, which in turn makes it hard for RB to load. Not impossible, but more typing than I’m really up for considering the plugin is working just fine at the moment.

If you have any tales of miserable bugs to share, feel free to do so; I’d like to think I’m not the only one that has them, even if they only appear once in a blue moon.

TWAIN Plugin

April 10th, 2009

I am currently in the middle of developing a TWAIN plugin for REALbasic. I will likely need testers at some point in the near future, so if you’d be interested in doing some beta testing for such a beast, I would be happy to hear from you.

DelayedAction Class

April 8th, 2009

There has been some talk on the REALbasic forums about how to handle the case of a delayed action. One obvious solution is creating a Timer subclass, but that can get old really fast if you would like to create a lot of different delayed actions. In the spirit of object-oriented programming, one would ideally have a reusable object that would execute some code (perform an action, or more plainly, run a method) after a given time delay.

The implementations at the forefront of this discussion were using an interface, and using delegates. After some careful thought, I have found both methods to be identical in functionality, but using an interface requires quite a bit of hoop-jumping if you want more than one action per class.

For both methods, parameters can either be stored automatically by the timer class, or by an external actor class. The former will require generic typing, destroying type safety, but keeps implementations flexible, whereas an external actor class can maintain a strictly-typed protocol.

The only true difference is when it comes to adding more than one action into a class. With a delegate, you simply call a different method. With an interface, you’re required to pass an identifier parameter that maps to which code you want executed, which must be shared knowledge between both the “queuer” and the “queuee” (if those are even words).

If you would like to see my implementation using delegates, please click here to download! In addition, please don’t be shy about commenting; I’d love to hear your opinions on the topic.

ActiveConnections fails to keep connections listed after StopListening()

April 6th, 2009

This problem may not actually be a bug, however if it is the intended behaviour, then there are some other considerations that need to be accounted for.

Let me start by describing the issue. Let’s say you have a ServerSocket listening away, with several clients connected. Now, let’s say one of the clients issues a shutdown command, which invokes a 30 second countdown before disconnecting all the other clients. First, you would expect that the server would stop listening for connections so no other users can get onto the server while it’s shutting down. In RB, you do this by calling ServerSocket.StopListening().

Now, the problem is, once you do that, the ServerSocket’s ActiveConnections array is cleared out. But, you still need to reference all of the sockets still connected so you can broadcast that 30 second countdown. Whoops, you’re out of luck.

Or are you? Couldn’t you just copy the ActiveConnections array before calling StopListening()? The answer to this is yes, but doing so introduces some other problems. If RB yields to the event loop during your loop that is copying the ActiveConnections array, that introduces a timeframe where more sockets could theoretically connect. The odds are slim, but in network programming, it’s better to code defensively than be sorry later when someone exploits your code.

Another variation of this is simply not calling StopListening until the countdown has happened, and you’ve disconnected all of the sockets. But you suffer from the exact same problem: a potential unexpected connection during or directly after disconnecting the connected sockets.

One could argue that this is not a big deal if your application is shutting down; all sockets are closed on application close anyway. However, this is a huge deal if your application is only disabling the networking component of its operation, as those orphaned sockets may stay connected until the application closes, and in a server environment, obviously, this happens as little as possible.

At any rate, I’ve written a small application that demonstrates the problem on 2009r1 for the QA guys down at REAL Software. I’ll share it with you too, if you’d like to test your version of RB as well.

Click Here to Download

Expression Calculator

April 2nd, 2009

For those of you looking to add a simple mathematical expression parser, this is the class you are looking for. Performs addition, subtraction, multiplication, division, negation, and handles bracketed expressions with ease.

If you’re feeling adventurous, you can also examine a hand-written lexical analyzer and recursive descent parser in action in REALbasic.

Download Now

A Better XML Interface

February 18th, 2009

While REALbasic is far ahead of many languages when it comes to abstracting away the nasties of program design, but there are some areas that still need a bit of work. One of those areas happens to be the XML classes. They do the job they’re supposed to do, but are very obviously direct wrappers to the underlying library: Expat.

XMLb strives to bridge the gap between simplicity and power with REALbasic’s XML reading and writing functionality.

Download (Alpha)

Affiliate

February 10th, 2009

I have joined the REAL Software’s new affiliate program, so now you can get your copy of REALbasic, and support me all at the same time.

Click here to get started.

Hashing Kit 1.0

February 5th, 2009

For those of you looking for the old hashing algorithms I had implemented in REALbasic: they can now be found here.

All of the hashing algorithms are now in one place. You can easily copy the entire library into your project, or hand-pick each algorithm you need by copying the appropriate module.

Also, the hashing digest interface is now defined. This allows you to dynamically switch out one digesting algorithm for another, should the need arise. Not only that, but it also allows contributors to write their own hashing digest classes and contribute to the library.

Currently I only have CRC32 and SHA512 implemented. If you would like to make a submission, please feel free to contact me.

Download Now