CTYPES problems: Need a way to pass through multiple structure

Thomas Heller theller at python.net
Mon Feb 10 05:57:45 EST 2003


mnations at airmail.net (Marc) writes:

> I am using CTYPES to integrate with a test box that included C type
> DLL's as the interface. This has worked very well for me until this
> impass. The interface expects the following format:
> 
> Declare Function HTGetStructure Lib "ETSMBW32" (ByVal iType1 As
> Long, ByVal iType2 As Long, ByVal iType3 As Long, ByVal iType4 As
> Long, pData As Any, ByVal uiLen As Long, ByVal iHub As Long, ByVal
> iSlot As Long, ByVal iPort As Long) As Long

What does "As Any" mean?

> 
> Or more plainly as:
> 
> HTGetStructure( STRUCTURE_TYPE, 0, 0, 0, *pointer to Structure Object,
> sizeof(Structure), a, b, c);

If it really means 'pass a pointer', then ok.

> 
> 
> An example:
> 
> 
> class HTCountStructure(Structure):
> 	_fields_ = [("uiMainLength", "h"),
> 		    ("ucPreambleByteLength", "B"),
> 		    ("ucFramesPerCarrier", "B"),
> 		    ("ulGap", "L")]
> count = HTCountStructure()
> windll.etsmbw32.HTGetStructure(20505,0,0,0,byref(count),sizeof(count),0,9,0)
> 
> 
> The function sizeof() is taken from mxTools.

Why? You *must* use the sizeof() from ctypes.  mxTools sizeof returns,
AFAIK, an estimation about how much memory this object requires, while
ctypes' sizeof function returns the size of the internal, C compatible
buffer of the HTCountStructure instance, and this is what the
HTGetStructure function expects.

> As long as I have standard variable types it works fine. However,
> the DLL later defines a structure as having a special variable
> length - U64, which uses two 32-bit longs:
> 
> typedef struct tagU64 {
> 	unsigned long	high;
> 	unsigned long	low;
> 	} U64;
> 
> It then uses the structure in the following way:
> 
> typedef struct tagETHExtendedCounterInfo {
> 	U64				u64RxVLANFrames;
> 	U64				u64RxIPFrames;		
>         U64				u64RxIPChecksumErrors;		
> 	unsigned long	                ulTxARPReplies;				
> 	unsigned long	                ulRxARPReplies;		
> ETHExtendedCounterInfo;
> 
> 
> CTYPES has a signed and unsigned 64 bit variable built in, but
> neither one of them worked. It's possible to nest a structure within
> a structure in CTYPES, and I performed this in the following way:
> 
> class U64(Structure):
> 	_fields_ = [("high", "L"),
> 		    ("low", "L")]
> 
> class ETHExtCounter(Structure):
> 	_fields_ = [("u64RxVLANFrames", "U64"),
> 		    ("u64RxIPFrames", "U64"),
> 		    ("u64RxIPChecksumErrors", "U64"),
> 		    ("ulTxARPReplies", "L"),
> 		    ("ulRxARPReplies", "L")]
You probably mean

class ETHExtCounter(Structure):
	_fields_ = [("u64RxVLANFrames", U64),
		    ("u64RxIPFrames", U64),
		    ("u64RxIPChecksumErrors", U64),
		    ("ulTxARPReplies", "L"),
		    ("ulRxARPReplies", "L")]

(without the quotes around U64).

> However, I still could not get the values to be returned from the test
> box to show up. Am I missing something?
> 
> If someone can spot my error I would greatly appreciate it. If not,
> then I am open to all theories on ways to go about this another way.
> This is something I really need to get working quickly.

You should also upgrade (if you haven't already) to the latest ctypes
release 0.4.0.

And then there's the ctypes-users mailing list, which should be the
right place to ask these questions.

Thomas




More information about the Python-list mailing list