On Mar 21, 4:04 am, Dennis Lee Bieber <[EMAIL PROTECTED]> wrote: > On Thu, 20 Mar 2008 16:50:18 -0700 (PDT), Craig <[EMAIL PROTECTED]> > declaimed the following in comp.lang.python: > > > > > I received a direct email from someone, and I came up with the > > following after implementing his advice: > > Just for completeness... I'm the "someone"... And this is a copy of > the message in question: > > > > > > > Please forgive my going direct -- I do not have Usenet posting > > privileges from work. > > > From your message: > > > -=-=-=-=-=-=- > > And, this is what printed: > > After - X = 4325376, CacheSize = 0, OpenMode = 3, vHandle = 17586736 > > > The printf shows that the values of X and vHandle have changed, but I > > am not sure it is working properly as X should be a MUCH smaller > > number (< 256). I would have expected a 0 (VIS_OK), 13 (VIS_DOS_ERROR) > > or 14(VIS_DISK_ERROR) if it had worked. > > > Next, I changed: > > fName = windll.oleaut32.SysAllocStringByteLen("u:\\msdb\\dcod\x00", > > 13) > > so that I knew it would not find the file, and got: > > After - X = 2555917, CacheSize = 0, OpenMode = 3, vHandle = 0 > > > The vHandle staying 0 tells me that it did not find the file, but the > > value of X seems random. > > -=-=-=-=-=-=-=- > > > X does NOT seem random to me -- but I took the effort to render it > > in hexadecimal. X seems to be coming back as a 32-bit integer. Your <256 > > code appears to be in the second half of that integer -- observe: > > > >>> "%8.8X" % 4325376 > > '00420000' > > >>> "%8.8X" % 2555917 > > '0027000D' > > > Also observe that x0D => 13 decimal... your stated "VIS_DOS_ERROR" > > code. > > > >>> 0x0042 > > 66 > > >>> 0x0027 > > 39 > > >>> 0x000d > > 13 > > > I have no explanation for the leading 16-bits... But under the > > rules of Python, "X = ..." is commonly a rebinding operation, so presetting > > X as a ctypes short integer may not be having any effect (I suspect those > > are more important for calls where the input parameters need to be mutable > > and of a known C format). > > > >>> import ctypes > > >>> x = ctypes.c_short(123) > > >>> dir(x) > > ['__class__', '__ctype_be__', '__ctype_le__', '__ctypes_from_outparam__', > > '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', > > '__init__', '__module__', '__new__', '__nonzero__', '__reduce__', > > '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', > > '_as_parameter_', '_b_base_', '_b_needsfree_', '_objects', '_type_', > > 'value'] > > > >>> x > > c_short(123) > > >>> x.value > > 123 > > > >>> x.value = 13 > > >>> x > > c_short(13) > > > Note that in this I have assigned to the "value" component of a > > c_short object. Plugging in your results values: > > > >>> x.value = 4325376 > > >>> x > > c_short(0) > > >>> x.value = 2555917 > > >>> x > > c_short(13) > > > Gives... ta da... 0 and 13 respectively. Perhaps you should, after creating > > X as a c short object, be assigning to the value, not to the object... > > > X.value = windll. ... > > > {Replies are being directed to my home email} > > -- > Wulfraed Dennis Lee Bieber KD6MOG > [EMAIL PROTECTED] [EMAIL PROTECTED] > HTTP://wlfraed.home.netcom.com/ > (Bestiaria Support Staff: [EMAIL PROTECTED]) > HTTP://www.bestiaria.com/
Sorry, I wasn't trying to exclude any credit from Dennis, I just wasn't sure if he wanted to be listed. As it turns out, I am running into more of these BSTR and pointer problems. I have moved on to the next function to convert: short FAR PASCAL VmxInfo(LPHANDLE lpDatasetNumber, LPVSTATS lpvstats); which uses a structure: typedef struct tagVSTATS { LONG nrecords; WORD gps_used; WORD gps_unused; WORD max_key_len; LONG grp_size; WORD init_alloc; WORD cr_opts; WORD free_prop_area; BSTR format; BSTR reserved; } VSTATS; typedef VSTATS FAR * LPVSTATS; This is what I have tried: from ctypes import * from ctypes.util import * libc = cdll.msvcrt printf = libc.printf LPBSTR = POINTER(c_void_p) HANDLE = POINTER(POINTER(c_long)) LPHANDLE = POINTER(HANDLE) LPSHORT = POINTER(c_short) LPVSTATS = POINTER(c_void_p) class VSTATS(Structure): _fields_ = [ ("nrecords", c_long), ("gps_used", c_short), ("gps_unused", c_short), ("max_key_len", c_short), ("grp_size", c_long), ("init_alloc", c_short), ("cr_opts", c_short), ("free_prop_area", c_short), ("format", c_void_p), ("reserved", c_void_p) ] vStats = VSTATS(1, 2, 3, 4, 5, 6, 7, 8) VmxInfo = windll.vbis5032.VmxInfo VmxInfo.restype = c_short VmxInfo.argtypes = [LPHANDLE, LPVSTATS] print "\n(2) VB/ISAM testing:" hwmcb = HANDLE() print "\nVmxInfo test:" res = c_short(255) printf ("Before - res = %#x (%d), hwmcb = %d\n", res, res, hwmcb) res = VmxInfo( byref(hwmcb), byref(c_void_p(vStats)) ) printf ("After - res = %#x (%d), hwmcb = %d\n", res, res, hwmcb) printf ("nrecords = %d, gps_used = %d, gps_unused = %d, max_key_len = %d\n", vStats.nrecords, vStats.gps_used, vStats.gps_unused, vStats.max_key_len) printf ("grp_size = %d, init_alloc = %d, cr_opts = %d, free_prop_area = %d\n", vStats.grp_size, vStats.init_alloc, vStats.cr_opts, vStats.free_prop_area) printf ("format = \x22%s\x22\n", vStats.format) printf ("reserved = \x22%s\x22\n", vStats.reserved) This is what I get: Traceback (most recent call last): File "C:\temp\vbisam_test_2.py", line 99, in <module> res = VmxInfo( byref(hwmcb), byref(c_void_p(vStats)) ) TypeError: cannot be converted to pointer And, on the last variation of this, this function needs to receive BSTR values passed back from the dll: short FAR PASCAL VmxGet(LPHANDLE lpDatasetNumber, LPSHORT lpSecIndex, LPSHORT lpOption, BSTR *SrchKey, BSTR *SecKey, BSTR *PriKey, LPSTR lpTypeDef); SrchKey is provided by me, SecKey and PriKey are returned by the dll, and TypeDef is defined by me and filled by the dll. For this, I have added: VmxGet = windll.vbis5032.VmxGet VmxGet.restype = c_short VmxGet.argtypes = [LPHANDLE, LPSHORT, LPSHORT, LPBSTR, LPBSTR, LPBSTR, LPBSTR] hwmcb = HANDLE() SecIndex = c_short(0) Option = c_short(17) SrchKey = windll.oleaut32.SysAllocStringByteLen("MSD19PH \x00", 41) SecKey = windll.oleaut32.SysAllocStringByteLen("1234567890123456789012345678901234567890\x00", 41) PriKey = windll.oleaut32.SysAllocStringByteLen("1234567890123456789012345678901234567890\x00", 41) TypeDef = windll.oleaut32.SysAllocStringByteLen(c_char_p("X".center(129, "\x00")), 129) print "\nVmxGet test:" res = c_short(255) printf ("Before - res = %#x (%d), SecIndex = %d, Option = %d, hwmcb = %d\n", res, res, SecIndex, Option, hwmcb) printf ("SrchKey = \x22%s\x22\nSeckey = \x22%s\x22\nPriKey = \x22%s \x22\nTypeDef = \x22%s\x22\n", SrchKey, SecKey, PriKey, TypeDef) print "Ready to call (Library = " + find_library("vbis5032") + ") ..." res = VmxGet( byref(hwmcb), byref(SecIndex), byref(Option), byref(c_void_p(SrchKey)), byref(c_void_p(SecKey)), byref(c_void_p(PriKey)), byref(c_void_p(TypeDef)) ) printf ("After - res = %#x (%d), SecIndex = %d, Option = %d, hwmcb = %d \n", res, res, SecIndex, Option, hwmcb) printf ("SrchKey = \x22%s\x22\nSeckey = \x22%s\x22\nPriKey = \x22%s \x22\nTypeDef = \x22%s\x22\n", SrchKey, SecKey, PriKey, TypeDef) The last message I get is: Ready to call (Library = C:\Windows\vbis5032.dll) ... and then I get a Windows popup box: python.exe has stopped working so, I know I am passing something very wrong. Once these two problems are resolved, I am sure I can process the rest of the C prototypes myself, as they are simply variations on these themes. As before, any help is appreciated. -- http://mail.python.org/mailman/listinfo/python-list