Dynamically loading DTWAIN DLL at runtime
Please note: If you are building a 64-bit application, you will be using DTWAIN64.DLL, not DTWAIN32.DLL.
Many times, it is desirable to load a dynamic link library at runtime using the Windows API LoadLibrary function. This allows your application to load a DLL programatically, check at runtime whether a DLL exists, and frees you from specifying an import library in your build settings. To do this, the Windows API LoadLibrary and GetProcAddress functions are used to accomplish this.
If you are programming in C or C++ and would like to use DTWAIN32.DLL or DTWAIN64.DLL using the LoadLibrary( ) call, the DYNDTWAIN_API structure has been created that will allow you to easily use LoadLibrary() . The DYNDTWAIN_API source files can be found in the DYDTWAIN subdirectory of the installation of DTWAIN.
The advantage of using the DYNDTWAIN_API structure is that you do not need to call GetProcAddress for each function -- the structure does this automatically.
However, The main advantage of using DYNDTWAIN_API is that your application does not use any DTWAIN import library files. This allows the Visual C++ programmer to not worry about runtime library compatibility with the DTWAIN import libraries (as was described in the previous section), or even the version of the compiler.
Also, any Windows C or C++ 32/64-bit compiler that recognizes the usual Microsoft extensions of __stdcall and __declspec is able to use DTWAIN easily without trying to create import libraries. If you are using a compiler that doesn't create import libraries, or it is very difficult to create import libraries, the DYNDTWAIN_API interface is what you should use.
Even if the compiler doesn't recognize these keywords, the header files can be easily edited to comply with your compiler. This allows any C++ compiler to use DTWAIN successfully, since there are no import libraries to deal with.
To use DYNDTWAIN_API, the following should be done:
By default, this line is commented out, therefore assumes that your project is not using precompiled headers. This line must not be commented out if your application
BOOL DYNDTWAIN_API::InitDTWAINInterface( HMODULE h );
For 'C' programmers, the InitDTWAINInterface takes two parameters and is a standalone function: BOOL InitDTWANInterface( DYNDTWAIN_API* pAPI, HMODULE h );
The pAPI in the 'C' call is a pointer to the DYNDTWAIN_API variable you created in step 2.
The following example is an outline of a typical scenario using DYNDTWAIN_API when building a 32-bit application. If the application is a 64-bit application, then the LoadLibrary( ) call in the code below should be:
Using C++: #include <dtwainx2.h>
int main( ) { // Declare a DYNDTWAIN_API variable DYNDTWAIN_API API; DTWAIN_SOURCE Source;
// Load the library HMODULE h = LoadLibraryA("DTWAIN32");
// Check if library loaded correctly. If so, initialize the DTWAIN // interface if ( h ) API.InitDTWAINInterface( h ); else return 0;
// Example DTWAIN calls
// This is DTWAIN_SysInitialize API.DTWAIN_SysInitialize();
// DTWAIN_SelectSource Source = API.DTWAIN_SelectSource( );
// DTWAIN_AcquireFile API.DTWAIN_AcquireFile(Source, "FILE.BMP", DTWAIN_BMP, DTWAIN_USENAME, DTWAIN_PT_DEFAULT, 1, TRUE, TRUE, NULL);
// DTWAIN_SysDestroy API.DTWAIN_SysDestroy(); ` // Once finished with DTWAIN, free the library FreeLibrary(h); }
Using 'C': #include <dtwainx2.h>
int main() { /* Declare a DYNDTWAIN_API variable */ DYNDTWAIN_API API; DTWAIN_SOURCE Source;
/* Load the library */ HMODULE h = LoadLibrary("DTWAIN32");
/* Check if library loaded correctly. If so, initialize the DTWAIN interface */ if ( h ) InitDTWAINInterface( &API, h ); else return 0;
/* Example DTWAIN calls */
/* This is DTWAIN_SysInitialize */ API.DTWAIN_SysInitialize();
/* DTWAIN_SelectSource */ Source = API.DTWAIN_SelectSource();
/* DTWAIN_AcquireFile */ API.DTWAIN_AcquireFile(Source, "FILE.BMP", DTWAIN_BMP, DTWAIN_USENAME, DTWAIN_PT_DEFAULT, 1, TRUE, TRUE, NULL);
/* DTWAIN_SysDestroy */ API.DTWAIN_SysDestroy();
/* Once finished with DTWAIN, free the library */ FreeLibrary(h); } For more advanced C++ programmers, you may want to encapsulate the DYNDTWAIN_API interface within another class so that the calls to LoadLibrary and FreeLibrary are done on construction and destruction, respectively. It wasn't done here so as to provide the most flexibility.
Also note that for C++, the functions are *static*. Therefore creation of an instance of DYNDTWAIN_API is not necessary (but was included in the examples above).
If your compiler doesn't support __stdcall or __declspec keywords, you will have a problem compiling your program. Note that it is very rare for a 32-bit Windows C / C++ compiler to not support these keywords. Even if the compiler doesn't support these keywords, the modules are easily editable to remove these words (or change them if the compiler uses different keywords).
|