Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to call two functions to allow my script to use ODMA but having a few problems, specifically (I think) with passing a pointer between the functions. I'm using
ApiLink ('odma32.dll', 'INT ODMRegisterApp(LPVOID FAR *pOdmHandle, DWO +RD version, LPSTR lpszAppld, DWORD dwEnvData, LPVoid pReserved)') || +die "blick"; $version = 100; $Appld = "PerlODMA"; $odmregisterrc = 0; $odmselectrc = 0; $flags = 0; $odmhandle = AllocMemory( 255 ); $docid = AllocMemory( 255 ); $odmregisterrc = ODMRegisterApp($odmhandle,$version,$Appld,$hwnd,undef +); ApiLink ('odma32.dll', 'INT ODMSelectDoc(LPVOID OdmHandle, LPSTR lpszD +ocid, LPDWORD pdwFlags)') || die "blick2"; $odmselectrc = ODMSelectDoc($odmhandle,$docid,$flags);
The first call works fine but the second causes perl to crash. Looking at the debug information from ODMA there's
ODMRegisterApp Input parameters: version=100(64) lpszAppId=PerlODMA; dwEnvData=2754366(2a073e) Output parameters: odmHandle=33949616(20607b0) Return value=0(0) ODMSelectDoc Input parameters: odmHandle=30705996(1d4894c)
which makes me think that the handle isn't being passed correctly, this should be the same between calls. The definitions for the functions are
#ODMStatus ODMRegisterApp(ODMHANDLE FAR *pOdmHandle WOrd version LPSTR + lpszAppld, DWORD dwEnvData, LPVoid pReserved) #ODMStatus ODMSelectDoc(ODMHANDLE odmhandle,LPSTR lpszDocid, LPDWORD p +dwFlags)
with ODMStatus being an int & ODMHandle being an LPVoid (based on typedefs in the sample C code for the odma library) The ODMA test system I'm using (and documentation) is at here
Any pointers? (to excuse the pun :)
George

Replies are listed 'Best First'.
Re: Win32 API Problem
by Anonymous Monk on Jan 04, 2004 at 23:05 UTC
    I've fiddled a little more and thanks to Devel::Peek I've found that what it's doing (I think) is using the memory address of the pointer in the 2nd procedure, rather than it's value. The memory itself seems to have had "something" put in it after running the first function so I'm guessing that bit's fine.
    I get the feeling that I'm so close yet so far :)
    George
Re: Win32 API Problem
by Roger (Parson) on Jan 04, 2004 at 23:58 UTC
    ... $odmhandle = AllocMemory( 4 ); # <-- 32 bit DWORD ... # retrieve and store the handle in $odmhandle $odmregisterrc = ODMRegisterApp($odmhandle, ...); # use the value of $odmhandle as 32bit DWORD ApiLink ('odma32.dll', 'INT ODMSelectDoc(DWORD OdmHandle, ...); $odmselectrc = ODMSelectDoc($odmhandle,$docid,$flags);
      Hi,
      I've tried this and it still crashes but from the log nothing appears to get to odmHandle in the 2nd function :/
      Thanks for having a look,
      George