Problem with c structs and byte arrays...maybe?

BlitzMax Forums/BlitzMax Programming/Problem with c structs and byte arrays...maybe?

fredborg(Posted 2005) [#1]
Hi,

I'm in the process of putting together a module that handles tablet/digitizer input in BlitzMax, and have encountered something weird.

I've converted the following C structure:
typedef struct tagLOGCONTEXT {
	char	lcName[40];
	UINT	lcOptions;
	UINT	lcStatus;
	UINT	lcLocks;
	UINT	lcMsgBase;
	UINT	lcDevice;
	UINT	lcPktRate;
etc...
Into this BMax code:
Type tagLOGCONTEXT
	Field lcName:Byte[40] 
	Field lcOptions:Int 
	Field lcStatus:Int 
	Field lcLocks:Int
	Field lcMsgBase:Int
	Field lcDevice:Int 
	Field lcPktRate:Int
etc.
Now this BMax type is passed to some C mumbo jumbo, but it doesn't work correctly. Apparently the lcName byte array is of a wrong size. If I however replace it with 10 Ints it's working perfectly.

Took me the best of 4 hours to figure that out.

Is it a bug, or me being dumb?


AntonyWells(Posted 2005) [#2]
You need to pad the C++ side version with dummy data as BB_Structs have their own internal data hidden from sight.


Russell(Posted 2005) [#3]
Also, (don't know if this will affect anything) the c struct is using unsigned Ints, whereas Max's are signed.

I do wish that Max supported unsigned and signed everything. Oh well, at least we have unsigned bytes and shorts now (yay!).

Russell


fredborg(Posted 2005) [#4]
Hi,

Antony, I can't really do that, as it interfaces with WinTab.dll which is a precompiled dll.

Russel, it doesn't matter (in this case) with signed vs. unsigned, as the ints never get big enough for it to be a problem.


fredborg(Posted 2005) [#5]
Hi,

I ended up doing it with a couple of methods, but it would be nice if someone had a simpler way.

Here's what the methods look like:
	Method toBank:TBank(buf:TBank)
		If buf = Null
			buf = CreateBank(33*4 + 40)
		Else
			ResizeBank(buf,33*4 + 40)
		EndIf
		For Local i:Int = 0 To 39
			PokeByte(buf,i,lcName[i])
		Next
		PokeInt(buf,40,lcOptions)
		PokeInt(buf,44,lcStatus)
		PokeInt(buf,48,lcLocks)
		PokeInt(buf,52,lcMsgBase)
		PokeInt(buf,56,lcDevice)
etc...
	Method fromBank(buf:TBank)
		If buf <> Null
			For Local i:Int = 0 To 39
				lcName[i] = PeekByte(buf,i)
			Next
			lcOptions = PeekInt(buf,40)
			lcStatus = PeekInt(buf,44)
			lcLocks = PeekInt(buf,48)
			lcMsgBase = PeekInt(buf,52)
			lcDevice = PeekInt(buf,56)
etc...
And then I use BankBuf() to pass the byte ptr to the c stuff, and convert back afterwards. Like this:
		Local tempbank:TBank = CreateBank()
		context.toBank(tempbank)
		WTInfo(WTI_DEFSYSCTX,0,BankBuf(tempbank))
		context.fromBank(tempbank)



skn3(Posted 2005) [#6]
Could try doing it like.. lcName:string="1234567890123456789012345678901234567890"
or
lcname:byte ptr = MemAlloc(40)