Need help calling a proprietary C DLL from Python

Craig craigm3604 at gmail.com
Thu Mar 20 19:50:18 EDT 2008


On Mar 20, 6:26 pm, sturlamolden <sturlamol... at yahoo.no> wrote:
> On 20 Mar, 19:09, Craig <craigm3... at gmail.com> wrote:
>
> > The following is the C++ prototype for one of the functions:
> > short FAR PASCAL VmxOpen(BSTR    *Filespec,
> >                          LPSHORT  lpLocatorSize,
> >                          LPSHORT  lpOmode,
> >                          LPHANDLE lphwmcb,
> >                          BSTR    *Password);
>
> import ctypes
> import comtypes
>
> LPBSTR = ctypes.POINTER(comtypes.BSTR)
> HANDLE = ctypes.POINTER(ctypes.POINTER(ctypes.c_long))
> LPHANDLE = ctypes.POINTER(HANDLE)
> LPSHORT = ctypes.POINTER(ctypes.c_short)
>
> VmxOpen = ctypes.windll.vbis5032.VmxOpen
> VmxOpen.restype = c_short
> VmxOpen.argtypes = [LPBSTR, LPSHORT, LPSHORT, LPHANDLE, LPBSTR]
>
> Filespec = comtypes.BSTR('blahblahblah')
> LocatorSize = ctypes.c_short(256)
> Omode = ctypes.c_short(1)
> hwmcb = HANDLE()
> Password = comtypes.BSTR('blahblahblah')
>
> res = WmxOpen( byref(Filespec), byref(LocatorSize),
>    byref(Omode), byref(hwmcb), byref(Password) )
>
> or if that fails:
>
> pFilespec = ctypes.pointer(Filespec)
> pLocatorSize = ctypes.pointer(LocatorSize)
> pOmode = ctypes.pointer(Omode)
> phwmcb = ctypes.pointer(hwmcb)
> pPassword = ctypes.pointer(Password)
>
> res = WmxOpen( pFilespec, pLocatorSize, pOmode, phwmcb, pPassword )

sturlamolden, thanks for the input.

I had to change your example to the following to get it to run:
from ctypes import *
import comtypes

LPBSTR = POINTER(comtypes.BSTR)
HANDLE = POINTER(POINTER(c_long))
LPHANDLE = POINTER(HANDLE)
LPSHORT = POINTER(c_short)

VmxOpen = windll.vbis5032.VmxOpen
VmxOpen.restype = c_short
VmxOpen.argtypes = [LPBSTR, LPSHORT, LPSHORT, LPHANDLE, LPBSTR]

Filespec = comtypes.BSTR('s:\\msdb\\dcod')
LocatorSize = c_short(0)
Omode = c_short(3)
hwmcb = HANDLE()
Password = comtypes.BSTR('GU32ASBURYPARK60A42A20')

res = VmxOpen( byref(Filespec), byref(LocatorSize), byref(Omode),
byref(hwmcb), byref(Password) )

print "res = " + str(res)

pFilespec = pointer(Filespec)
pLocatorSize = pointer(LocatorSize)
pOmode = pointer(Omode)
phwmcb = pointer(hwmcb)
pPassword = pointer(Password)

res = VmxOpen( pFilespec, pLocatorSize, pOmode, phwmcb, pPassword )

print "res = " + str(res)


After changing the assignment for Password to the correct value, both
calls to VmxOpen returned a status of 20, which indicates an invalid
password.

I received a direct email from someone, and I came up with the
following after implementing his advice:
from ctypes import *
from ctypes.util import *
libc = cdll.msvcrt
printf = libc.printf
FileSpec = windll.oleaut32.SysAllocStringByteLen("s:\\msdb\\dcod\x00",
13)
printf ("FileSpec = \x22%s\x22\n", FileSpec)
Password = windll.oleaut32.SysAllocStringByteLen("XYZ\x00", 4)
printf ("Password = \x22%s\x22\n", Password)
LocatorSize = c_short(0)
Omode = c_short(3)
hwmcb = c_long(0)
X = c_short(0)
printf ("Before - X = %#x (%d), LocatorSize = %d, Omode = %d, hwmcb =
%d\n", X, X, LocatorSize, Omode, hwmcb)
print "Ready to call (Library = " + find_library("vbis5032") + ") ..."
X.value = windll.vbis5032.VmxOpen(byref(c_void_p(FileSpec)),
byref(LocatorSize), byref(Omode), byref(hwmcb),
byref(c_void_p(Password)))
printf ("After - X = %#x (%d), LocatorSize = %d, Omode = %d, hwmcb = %d
\n", X, X, LocatorSize, Omode, hwmcb)
windll.oleaut32.SysFreeString(FileSpec)
windll.oleaut32.SysFreeString(Password)


This returned a correct value in X of 0 (VIS_OK).

When I changed:
FileSpec = windll.oleaut32.SysAllocStringByteLen("s:\\msdb\\dcod\x00",
13)
to:
FileSpec = windll.oleaut32.SysAllocStringByteLen("u:\\msdb\\dcod\x00",
13)
I got the expected X value of 13 (VIS_DOS_ERROR).

As was pointed out to me, and not really to my surprise as I am still
very "green" at Python, the correct call was:
X.value = windll.vbis5032.VmxOpen(byref(c_void_p(FileSpec)),
byref(LocatorSize), byref(Omode), byref(hwmcb),
byref(c_void_p(Password)))
instead of:
X = windll.vbis5032.VmxOpen(byref(c_void_p(FileSpec)),
byref(LocatorSize), byref(Omode), byref(hwmcb),
byref(c_void_p(Password)))


Thank you to everyone for their help.



More information about the Python-list mailing list