On Mar 22, 3:13 pm, Dennis Lee Bieber <[EMAIL PROTECTED]> wrote: > On Fri, 21 Mar 2008 23:21:48 -0700 (PDT), Craig <[EMAIL PROTECTED]> > declaimed the following in comp.lang.python: > > > Sorry, I wasn't trying to exclude any credit from Dennis, I just > > wasn't sure if he wanted to be listed. > > As responded to elsewhere -- it was more a case of minimizing the > "non-work" traffic on my work email address... > > <snip> > > > This is what I have tried: > > <snip> > > > LPBSTR = POINTER(c_void_p) > > <snip> > > > 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] > > Remember that Python strings are immutable... Also note that the > signature you give above seems to differentiate between passing a > pointer variable LPSTR (ie; lpTypeDef is just 4-bytes which will/should > contain the address pointing to the real string) and passing the address > of the first byte of a string buffer BSTR (*PriKey is the same as > &PriKey[0] -- but PriKey itself has to be a sequence of characters or an > empty buffer allocated to hold them). > > From the ctypes documentation: > http://docs.python.org/lib/node453.html > > """ > Assigning a new value to instances of the pointer types c_char_p, > c_wchar_p, and c_void_p changes the memory location they point to, not > the contents of the memory block (of course not, because Python strings > are immutable): > > >>> s = "Hello, World" > >>> c_s = c_char_p(s) > >>> print c_s > > c_char_p('Hello, World')>>> c_s.value = "Hi, there" > >>> print c_s > > c_char_p('Hi, there') > > >>> print s # first string is unchanged > Hello, World > > You should be careful, however, not to pass them to functions expecting > pointers to mutable memory. If you need mutable memory blocks, ctypes > has a create_string_buffer function which creates these in various ways. > The current memory block contents can be accessed (or changed) with the > raw property; if you want to access it as NUL terminated string, use the > value property: > > >>> from ctypes import * > >>> p = create_string_buffer(3) # create a 3 byte buffer, initialized to > >>> NUL bytes > >>> print sizeof(p), repr(p.raw) > 3 '\x00\x00\x00' > >>> p = create_string_buffer("Hello") # create a buffer containing a NUL > >>> terminated string > >>> print sizeof(p), repr(p.raw) > 6 'Hello\x00' > >>> print repr(p.value) > 'Hello' > >>> p = create_string_buffer("Hello", 10) # create a 10 byte buffer > >>> print sizeof(p), repr(p.raw) > > 10 'Hello\x00\x00\x00\x00\x00'>>> p.value = "Hi" > >>> print sizeof(p), repr(p.raw) > > 10 'Hi\x00lo\x00\x00\x00\x00\x00' > > """ > > Drawback -- it looks like you may have to preset the size of the > buffer... > > -- > Wulfraed Dennis Lee Bieber KD6MOG > [EMAIL PROTECTED] [EMAIL PROTECTED] > HTTP://wlfraed.home.netcom.com/ > (Bestiaria Support Staff: [EMAIL PROTECTED]) > HTTP://www.bestiaria.com/
That is not really a drawback. Pretty much everything is fixed-length anyway. I guess I am having trouble with the whole immutable thing. And, the pointers too. Anyway, I have the following for "types": LPBSTR = POINTER(c_void_p) HANDLE = POINTER(POINTER(c_long)) LPHANDLE = POINTER(HANDLE) LPSHORT = POINTER(c_short) LPVSTATS = POINTER(c_void_p) c_string = c_char_p LPSTR = c_string I guess passing a structure is out of the question. So, I tried a string (something - just to get the data back): #short FAR PASCAL VmxInfo(LPHANDLE lpDatasetNumber, LPVSTATS lpvstats); VmxInfo = windll.vbis5032.VmxInfo VmxInfo.restype = c_short VmxInfo.argtypes = [LPHANDLE, LPSTR] VsamInfo = create_string_buffer("12345678901234567890123456789012") printf ("VsamInfo = \x22%s\x22\n", VsamInfo.raw) print "Ready to call (Library = " + find_library("vbis5032") + ") ..." res = VmxInfo( byref(hwmcb), byref(VsamInfo) ) And I get: Ready to call (Library = C:\Windows\vbis5032.dll) ... Traceback (most recent call last): File "C:\temp\vbisam_test_2.py", line 101, in <module> res = VmxInfo( byref(hwmcb), byref(VsamInfo) ) ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: wrong type So, to get to the VmxGet, I comment out the VmxInfo call, and proceed to: SrchKey = windll.oleaut32.SysAllocStringByteLen("MSD19PH \x00", 41) SecKey = windll.oleaut32.SysAllocStringByteLen("1234567890123456789012345678901234567890\x00", 41) PriKey = windll.oleaut32.SysAllocStringByteLen("1234567890123456789012345678901234567890\x00", 41) TypeDef = create_string_buffer("X".center(129, "X")) 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)) ) And for this, I get: Ready to call (Library = C:\Windows\vbis5032.dll) ... Traceback (most recent call last): File "C:\temp\vbisam_test_2.py", line 114, in <module> res = VmxGet( byref(hwmcb), byref(SecIndex), byref(Option), byref(c_void_p(S rchKey)), byref(c_void_p(SecKey)), byref(c_void_p(PriKey)), byref(TypeDef) ) ctypes.ArgumentError: argument 7: <type 'exceptions.TypeError'>: wrong type I know I am missing something, probably very basic (pardon the pun) to Python. -- http://mail.python.org/mailman/listinfo/python-list