Need help calling a proprietary C DLL from Python
Craig
craigm3604 at gmail.com
Tue Mar 25 11:24:13 EDT 2008
On Mar 25, 2:02 am, Dennis Lee Bieber <wlfr... at ix.netcom.com> wrote:
> On Mon, 24 Mar 2008 15:21:11 -0700 (PDT), Craig <craigm3... at gmail.com>
> declaimed the following in comp.lang.python:
>
> > And this is what I got:
> > VmxGet test - looking for valid record...
> > Before - PriKey = 0x0044F56C, SecKey = 0x0044F534
> > ci_PriKey = 0x0044F56C, ci_SecKey = 0x0044F534
> > After - PriKey = 0x0044F56C, SecKey = 0x0044F534
> > ci_PriKey = 0x0043D49C, ci_SecKey = 0x0043D484
>
> So VmxGet() DID allocate new BSTR structures.
>
> It might be interesting to extract the length data that is part of
> the BSTR and compare.
>
> ctypes.string_at(PriKey - 4, 4) #if I recall the arguments
> vs
> ctypes.string_at(ci_PriKey - 4, 4)
>
> If the second (after conversion to integer) is larger than the
> former, it could mean that the routine checks what is passed in to
> ensure enough storage space, and if it won't fit, does the allocation.
>
> If it were always going to do an allocation, there would have been
> no excuse for /reading/ the passed in structure length.
> --
> Wulfraed Dennis Lee Bieber KD6MOG
> wlfr... at ix.netcom.com wulfr... at bestiaria.com
> HTTP://wlfraed.home.netcom.com/
> (Bestiaria Support Staff: web-a... at bestiaria.com)
> HTTP://www.bestiaria.com/
I changed to the following to followup on the length data:
printf ("Before - PriKey = 0x%8.8X, SecKey = 0x%8.8X\n", PriKey,
SecKey)
printf (" ci_PriKey = 0x%8.8X, ci_SecKey = 0x%8.8X\n",
ci_PriKey.value, ci_SecKey.value)
res = VmxGet( byref(hwmcb), byref(SecIndex), byref(Option),
byref(c_void_p(SrchKey)), byref(ci_SecKey), byref(ci_PriKey),
TypeDef )
printf ("After - PriKey = 0x%8.8X, SecKey = 0x%8.8X\n", PriKey,
SecKey)
printf (" ci_PriKey = 0x%8.8X, ci_SecKey = 0x%8.8X\n",
ci_PriKey.value, ci_SecKey.value)
print ord(string_at(PriKey - 4, 1)), ord(string_at(PriKey - 3, 1)),
ord(string_at(PriKey - 2, 1)), ord(string_at(PriKey - 1, 1))
print ord(string_at(ci_PriKey.value - 4, 1)),
ord(string_at(ci_PriKey.value - 3, 1)), ord(string_at(ci_PriKey.value
- 2, 1)), ord(string_at(ci_PriKey.value - 1, 1))
And, got:
Before - PriKey = 0x0028B6FC, SecKey = 0x0028B6C4
ci_PriKey = 0x0028B6FC, ci_SecKey = 0x0028B6C4
After - PriKey = 0x0028B6FC, SecKey = 0x0028B6C4
ci_PriKey = 0x0027D284, ci_SecKey = 0x0027D26C
41 0 0 0
7 0 0 0
Which makes sense for two reasons:
1. It would only return the non-space-filled part of the returned key.
2. At least from VB6, the variable does not even have to be used
before the call.
I have gone on to design a function for printing the contents as
fields in a Structure.
def DCOD_Print():
temp = unpack(DecoderRecordFormat, TypeDef.raw)
DCOD = DecoderRecord(temp[0], temp[1], temp[2], temp[3], temp[4],
temp[5])
print " DistID = \x22%s\x22" % DCOD.DistID
print " YearCode = \x22%s\x22" % DCOD.YearCode
print " AccountType = \x22%s\x22" % DCOD.AccountType
print "AccountNumber = \x22%s\x22" % DCOD.AccountNumber
print " Description = \x22%s\x22" % DCOD.Description
print " Unused = \x22%s\x22" % DCOD.Unused
return
class DecoderRecord(Structure):
_fields_ = [
("DistID", c_char_p),
("YearCode", c_char_p),
("AccountType", c_char),
("AccountNumber", c_char_p),
("Description", c_char_p),
("Unused", c_char_p)
]
DecoderRecordFormat = "3s4ss32s32s56s"
Then, a simple:
print DCOD_Print()
parses the record into its fields, and displays those fields.
In other files, some of those fields are VB6 currency types, which
have been described as 8-byte integers with an implied 4 decimal
places (which I guess would be __int64 or c_longlong and then divide
by 10,000, or simply put a decimal point 4 away from the end).
Any ideas on how best to process this type of data in Python?
More information about the Python-list
mailing list