Forum Replies Created
- AuthorPosts
@jimwatters wrote:
How is Apple getting around this on 64bit if they are passing pointers?
I don’t know. My app was 32-bit, so I was able to use it to pass along an Objective-C self pointer.
However, according to the file command, the TWAIN binary for OS 10.5 supports four architectures: ppc7400, ppc64, i386, and x86_64. OS X also supports thread-local storage (not that it’s hard to implement on your own). And, of course, you can just be dirty and use a global, if you are sure it won’t be an issue for your app.
Modifying the application name might unwanted have side effects. Some DS choose to store the last used settings for each Application name that opens it. If the name keeps changing you might not get the settings you expected.
In that connection, I noticed that the DSM will let you open multiple appId blocks, as long as the product names are different (it doesn’t consider the manufacturer or product family fields). I assume that’s what you would need to do if you wanted to drive multiple devices simultaneously. The message queue that the Windows window handle supports is per-thread, and the handle is per DSM app, not per source. So, to drive eight scanners at once, you would start up eight threads, each of which would open the DSM with a slightly different product name … ScannerMaster 1, ScannerMaster 2, etc.
BTW, I found that my problem with the dummy software datasource hanging under DSM 2 went away if I supplied a window handle on the open. I had ripped out the window handle code, so I put it back in.
I, too, assumed that the RefCon value was intended for passing back context variables such as this pointers. It works fine for that on the Mac. The Mac implementation relies entirely on the callback and does not need an event pump.
The 2.0 DSM is broken. When I discovered the RefCon passback was not implemented, I decided just to ignore the callback feature on Windows. That worked fine for the Epson scanner I was using for tests. However, when I tested with the TWAIN dummy software source, it blocked on the GetMessage call, even though I had not defined a callback. Reverting back to twain_32.dll (and supplying a window handle to DSM_Entry on startup) worked fine with the software source. So, that made me worry that future drivers for real devices might rely on the callback being there for the 2.0 DSM, causing apps that don’t implement it to hang.
The docs also do not make it clear that, on Windows, you need to implement both the callback and the event pump. I assumed it would work like the Mac — no more message pump. But when I tried that with the Epson, it showed empty UI windows, making it obvious the event pump was still needed.
I looked at the TWAIN sample application. It implements the callback, but uses a global variable to track it. That’s poor coding practice: globals are not thread-safe.
One possibility would be to store your this pointer in thread local storage (google TlsAlloc and friends). Another might be to cram it past the end of your manufacturer or product name in the appId and make sure your name string is 29 characters or less (better make that 25 to allow for 64-bit).
- AuthorPosts