Home › Forums › TWAIN Classic › Calling the source manager
- This topic has 8 replies, 4 voices, and was last updated 14 years, 1 month ago by Mar.
- AuthorPosts
How do you call the source manager from VC++? I copied the code from the specification but it fails with:
Error 1 error C2197: ‘int (__stdcall *)(void)’ : too many arguments for callrc=(*pProc)(&twApp, 0, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, Wrapper::Caller);
Then I tried microsofts example and got :
Error 1 error C2197: ‘FARPROC’ : too many arguments for callrc=pProc(&twApp, 0, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, Wrapper::Caller);
They both appear to have the same thing wrong with them, but I don’t know what it is.
Here is the code I use for opening the DLL:
#define TWAIN_Dll "TWAIN_32.DLL"
static HANDLE hDllModule;
//static DSMENTRYPROC pProc;
static FARPROC pProc;
static TW_IDENTITY twApp;
bool LoadDll()
{
//long Ordinal;
//hDllModule=LoadLibrary(LPCWSTR (TWAIN_Dll));
hDllModule=LoadLibraryA(TWAIN_Dll);
//if (hDllModule>=(HANDLE)VALID_HANDLE)
if (hDllModule!=NULL)
//{ Ordinal=MAKELONG(1,0);
// pProc=GetProcAddress(HMODULE (hDllModule), LPCSTR(MAKEINTRESOURCE(Ordinal)));
{ pProc=GetProcAddress(HMODULE (hDllModule), LPCSTR(MAKEINTRESOURCE(1)));
if (pProc!=0)
bDllLoaded=true;
else
bDllLoaded=false;}
else
bDllLoaded=false;
return bDllLoaded;
}
I suspect the problem is with GetProcAddress, since it complains with: 1 error C2664: ‘GetProcAddress’ : cannot convert parameter 2 from ‘LPWSTR’ to ‘LPCSTR’ . Why does an ordinal need to be cast to a LPCSTR? Its not done that way in the example. However it refuses to compile without it.
I tried using MAKELONG because I saw it in another forum, but it doesn’t change anything.
I cannot define something as DSMENTRYPROC because the compiler does not recognize it.
I also tried calling LoadLibrary with both unicode and ansi, not that I thought it would matter, but I am trying everything.
Any assistance is appreciated. Thanks for looking.
You need to include twain.h
#include "twain.h"
There is no UNICODE version of GetProcAddress.
The following is from a non-UNICODE build.//load the TWAIN source manager DLL
HMODULE hDSM = LoadLibrary("TWAIN_32.DLL");
if(hDSM!=NULL)
{
//get the address of the TWAIN entry procedure
DSMENTRYPROC pDSMEntry = (DSMENTRYPROC)GetProcAddress(hDSM, "DSM_Entry");
if(pDSMEntry)
...Jim Watters
Thanks for your quick reply Jim. I will make those changes immediately!
Thanks for the assistance. I’ve made some progress (because of your help), now it compiles!! However I get a failure when I try to call it: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. This error propagates up from the C code to VB.
A VB.NET app (managed code) is calling the C++ code (also managed). Do I have to do something so the TWAIN Dll can write to the structure? i was forced to change something in your example, since I was getting this error: error C2664: ‘LoadLibraryW’ : cannot convert parameter 1 from ‘const char [13]’ to ‘LPCWSTR’.
HMODULE hDllModule=LoadLibraryA(TWAIN_Dll);
Here is the code that makes the call:
bool Wrapper::DSM_Open()
{
int rc, hWnd;
//Populate the structure that will be used for communication
lstrcpyA (twApp.Manufacturer, "Rotair Industries");
lstrcpyA (twApp.ProductFamily, "Mar's work");
lstrcpyA (twApp.ProductName, "RFQ Console");
twApp.ProtocolMajor = 2;
twApp.ProtocolMinor = 1;
twApp.SupportedGroups = DG_IMAGE;
twApp.Version.Country = TWCY_USA;
lstrcpyA (twApp.Version.Info, "2.0");
twApp.Version.Language = TWLG_ENGLISH_USA;
twApp.Version.MajorNum = 2;
twApp.Version.MinorNum = 0;
//Open the DSM (Data Source Manager)
hWnd = Wrapper::Caller;
rc=(*pProc)(&twApp, 0, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, (TW_MEMREF) Wrapper::Caller);
//rc=pProc(&twApp, 0, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, (TW_MEMREF) hWnd);
if (rc==TWRC_SUCCESS)
return true;
else
return false;
}Thanks for looking.
at least last parameter in DSM_Entry has to be address of handle. in your code this is not clear
also, is getprcoaddress call successful?
Thanks for your reply Denis. I got 0x5B2D3B35 back for pProc, so I assume it was successful. I apologize for my low level of C++ skills, but I can’t get it to work under VB and my boss wants this done.
I changed the call to this hoping it is what you meant:
rc=pProc(&twApp, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, (TW_MEMREF) &hWnd);
But I still get the error. i am starting to think that the unmanaged C dll can not write to memory that was allocated by managed code. Does this make any sense? Is there any way to define or allocate the structure in managed code so it can be used by the DSM?
When you say “…the C++ code (also managed)” is this a Windows Forms project?
.
It is a windows forms project, VB.NET. When I couldn’t get it to work under VB.NET I thought of trying to set the capabilities from a C++ dll. But I couldn’t pass the TW_IDENTITY structure from VB to C++. It wouldn’t even compile. So then I tried putting all the TWAIN calls in C++ (I am a novice C++ programmer) but I get a protected memory error. Being a VB programmer, this is a new concept for me 🙂 I am still struggling with it.
I am going to look at the openTwain, because that is proof that there is someone on the net who proved it can be done in VB.
I am going to do this entirely in VB with help from openTwain. This is being abandoned.
- AuthorPosts