Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 6
Specifically I modified the TWAIN_UnloadSourceManager() method. I had to ensure all the pointers were set to null, otherwise the DLL would not properly unload the source manager.
After I changed the source code, the Java application responded without errors. The native Win32 environment didn't need these
changes, as the DLL unloaded properly
Though the low-level plumbing is set up, communication between Java and Win32 will still present problems. Java has difficulty integrating with hardware devices because of the Win32 message pump. Java has no real way to connect to the event handlers in the Win32 world. Instead, you must create a proxy window, so it, not the Java application, can receive the Win32 SDK messages.
That approach negates the need to pass the HWND parameter to EZTwain DLL; instead we can use a null HWND as a parameter within the DLL. When the EZTwain 1.x DLL detects a null, it creates a proxy window, hides it, and uses it
for pumping message handlers. The Java client is relieved of the HWND responsibility, simplifying the bridge between the two layers.
Note: That technique proves useful for synchronous hardware devices like Twain or utility libraries that lack a real GUI. With
Twain, you pass it a command, the vendor-supplied dialog appears, the acquisition occurs, and then Twain eventually returns
a DIB. However, be aware that, with TAPI (Telephony Application Programmers Interface) and other asynchronous technologies,
passing a null HWND will not suffice. Further processing of call-back methods may be required. Asynchronous hardware devices need both the application
and the DLL to participate in two-way communication via the Win32 message handlers. As Java clients cannot take part, more
complex solutions are required: perhaps a TCP/IP socket server.
Now we need to map the previous flow of events to an actual interface in the JNI layer. We must write the exact number of JNI methods required to realize the use-case—no more and no less. Strictly adhering to RUP keeps us focused. The sequence diagram depicts the user actor going through the use-case and exercising our API. I detail the methods below:
The JNI method jboolean Java_org_scavino_twain_JTwain_isTwainAvailble() allows an application to test for Twain's existence. This method accomplishes Step 1 in the use-case's primary flow. isTwainAvailble() does not confirm whether your particular Twain device is enabled or even attached to the machine. It merely tests for the
existence of the twain.dll in your path and verifies that you have at least one Twain device installed. This result is cached after the Twain library
has been prodded. A more elaborate exception-handling mechanism could replace the simple boolean return type. Again, the current goal is simplicity, and a future iteration could have exception handling in the interface.