Announcement

Collapse
No announcement yet.

data conversion from a "C" struct

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • data conversion from a "C" struct

    I'm interfacing to a SDK that uses "C" structs and DLL's. Everything is going well, except I'm having trouble with one data element in a struct. It is:

    char time[3]

    I've tried converting this to

    time asciiz *3

    but, it gives me garbage. I've tried other formats, too, such as byte. All to no avail. Can someone tell me the proper conversion for this piece of data?

    Thanks,
    Dale

    ------------------

  • #2
    Have you tried time as string * 3?


    ------------------
    Neil Bertz
    [email protected]
    PowerBASIC Staff

    Comment


    • #3
      Thanks, Neil, but it didn't work.

      I did find out that each char holds a different time unit: hours, minutes, seconds.

      So, I did a lot of experimenting. I am able to get good data if I use bytes, instead of asciiz or string, integer, etc.

      However, I can only get the minutes and seconds. Hours are no where to be found.... Any ideas why, or what to do about it?

      Thanks,
      dale

      ------------------

      Comment


      • #4
        What did your UDT look like, then?

        I would image it must look like this:
        Code:
        TYPE udttypename
          ...
          hms AS BYTE(1 TO 3) ' or may be smh (reverse order)
          ...
        or maybe:
        Code:
          ...
          h AS BYTE
          m AS BYTE
          s AS BYTE
          ...
        If this does not help, please post some of the C code that uses these member items.

        Thanks!

        ------------------
        Lance
        PowerBASIC Support
        mailto:[email protected][email protected]</A>
        Lance
        mailto:[email protected]

        Comment


        • #5
          char time[3] and some logic.

          If you get s and m but not h from a char time[3] then it seems,
          that the c++ source defaults "char = single byte" to
          "wchar = double byte".

          that means, you should try to pass a buffer of 6 bytes.
          this buffer might look

          Code:
          Type TimeType WORD 'word means align to 2 bytes
              h as byte
              m as byte
              s as byte
          End Type
           
          'or
           
          'Dim m_Time(0 to 5) as WORD ' error due coffee underrun
          Dim m_Time(0 to 5) as BYTE ' would match correct
          Function ProcessTimeStruct(timeStruct as WORD PTR, Byref h as WORD, Byref m as WORD, Byref s as Word) as LONG
              
              h = timeStruct[0]
              m = timeStruct[1]
              s = timeStruct[2]
              
          End Function
          
          Function MAIN
              Dim h as Word, m as Word, s as Word
              Call YourCPPFunction(m_Time_By_Ref_OR_Ptr_To_m_Time_Byal)
              Call ProcessTimeStruct(m_Time, h,  m, s)
          End Function

          ------------------


          [This message has been edited by Torsten Rienow (edited December 07, 2001).]

          Comment


          • #6
            Good thinking Torsten! I think you may have nailed it.

            ------------------
            Lance
            PowerBASIC Support
            mailto:[email protected][email protected]</A>
            Lance
            mailto:[email protected]

            Comment


            • #7
              I've never seen "char" mutate away from byte-size. "CHAR", maybe, but
              "CHAR" is not "char". It may be that the problem is due to an alignment
              error. Perhaps you could post the original struct?


              ------------------
              Tom Hanlin
              PowerBASIC Staff

              Comment


              • #8
                I suspect it is an alignment issue, but I haven't been able to trace it down. When I use the bytes as I mentioned the following data is valid, ONLY if I use just 2 bytes (minutes and seconds).

                Here are the original structs in c. As you can see, it is multi-layered:
                Code:
                	typedef struct {					// intraday update - sale message
                		char	time[3];
                		char	format;
                		long	seq;					// unique seq # of this trade
                		long	value;
                		long	volume;
                		char	saleCode;				// a code defining the type of sale
                	} SALE_UPDATE;
                	
                	typedef struct {					// intraday update - quote message					
                		char	time[3];
                		char	format;
                		long	seq;					// unique seq # of this quote
                		long	bid;
                		long	ask;
                		USHORT	bidSize;
                		USHORT	askSize;
                	} QUOTE_UPDATE;
                	
                	typedef	struct {					
                		UCHAR	error;					
                		UCHAR	recordType;
                		char	flag;					// see below
                		char	msgType;				// 0=trade  1=quote
                		union	{							
                			SALE_UPDATE		sale;
                			QUOTE_UPDATE	quote;
                		} m;
                	} INTRADAY_UPDATE;
                
                
                /*		the flag will denote the type of data.  there are 3 possibilities:
                		0 is for a regular msg, 1 is for a cancellation of a previous msg.
                		the msg to be cancelled is the one with the same sequence # that is in
                		this msg.  2 is for a correction - replace the msg with the seq #
                		that is sent with this msg with the data in this msg (new volume & last)
                
                		not all fields are defined for each record type:
                		the following are the valid fields per type of record
                
                		for Sale (a trade):
                
                		type		time	format	seq		value	volume	saleCode
                		----		-----	------	-----	-----	----	--------
                
                  0		stock		Yes		Yes		Yes		Yes		Yes		Yes		
                  1		index		Yes		Yes		Yes		Yes		No		No	
                  2		option		Yes		Yes		Yes		Yes		Yes		No	
                  3		reg stock	Yes		Yes		Yes		Yes		Yes		Yes	
                  4		mkt stat	Yes		Yes		Yes		Yes		No		No	
                  5		future		Yes		Yes		Yes		Yes		Yes		No
                  
                
                	time = <hour> <minute> <second>
                	saleCode = trade code - usually a blank  - see file stockCodes.stcd
                	
                //		now define the overall myTrack msg that will come back from the server
                
                
                	typedef struct {
                		short	messageCode;			// defines what type of message this is
                		short	spare;
                		int		rqn;					// the turn around data 
                		union	{
                			ERROR_REPORT		errorReport;
                			LOGON_RESPONSE		logonResponse;
                			LOGOFF_RESPONSE		logoffResponse;
                			     <snip -- there are many more structs to this union>
                			INTRADAY_UPDATE		tick;
                  			     <snip>
                			BROKER_ACCT_ORDER       brokerOrder;
                                        BROKER_ACCT_CASH_TRANSACTION brokerCashTransaction; // MSG_BROKER_CASH_TRANSACTION 
                			BROKER_ERROR_MESSAGE	errorMessage;	// MSG_BROKER_ERROR_MESSAGE
                		} u;
                	} MYTRACK_MSG;
                I converted this into the following PB code:
                Code:
                TYPE SALE_UPDATE
                   time(2) AS BYTE             ' can only use 2 bytes, or following
                                               ' fields are out of sequence (min & sec)
                   format AS BYTE   
                   seq AS LONG
                   value AS LONG           ' should be byte? Works this way
                   volume AS LONG          ' should be byte? Works this way
                   saleCode AS ASCIIZ *1
                END TYPE
                
                TYPE QUOTE_UPDATE
                   time AS ASCIIZ *3
                   format AS ASCIIZ *1
                   seq AS LONG
                   bid AS LONG
                   ask AS LONG
                   bidSize AS WORD      ' should be dword?
                   askSize AS WORD      ' should be dword?
                END TYPE
                
                UNION update
                   sale AS SALE_UPDATE
                   quote AS QUOTE_UPDATE
                END UNION
                
                TYPE INTRADAY_UPDATE
                   terror AS BYTE
                   recordType AS BYTE
                   flag AS BYTE 
                   msgType AS BYTE               ' 0 = trade; 1 = quote
                   m AS update
                END TYPE ' INTRADAY_UPDATE
                
                
                UNION response
                   errorReport AS ERROR_REPORT
                   logonResponse AS LOGON_RESPONSE
                       <snip>
                   tick AS INTRADAY_UPDATE
                       <snip>
                   errorMessage AS BROKER_ERROR_MESSAGE
                END UNION   ' response
                
                   '       now define the overall myTrack msg that will come back from the server
                TYPE MYTRACK_MSG
                   messageCode AS INTEGER
                   spare AS INTEGER
                   rqn AS LONG
                   resp AS response
                END TYPE ' MYTRACK_MSG
                I included all the struct/type layers in case I made a translation error somewhere earlier in the heirarchy. When I look at data in the higher levels, it seems to check out.

                Thanks for your help.
                Dale

                ------------------

                Comment


                • #9
                  Originally posted by Dale Gillilan:
                  Here are the original structs in c. As you can see, it is multi-layered:
                  Code:
                  typedef struct {					// intraday update - sale message
                  	char	time[3];
                  	char	format;
                  	long	seq;					// unique seq # of this trade
                  	long	value;
                  	long	volume;
                  	char	saleCode;				// a code defining the type of sale
                  } SALE_UPDATE;
                  	
                  <snip>
                  TYPE SALE_UPDATE
                     time(2) AS BYTE             ' can only use 2 bytes, or following
                                                 ' fields are out of sequence (min & sec)
                     format AS BYTE   
                     seq AS LONG
                     value AS LONG           ' should be byte? Works this way
                     volume AS LONG          ' should be byte? Works this way
                     saleCode AS ASCIIZ *1
                  END TYPE
                  I note that in the C code, the 1st 2 elements add up to 4 bytes, so I think your original declaration is the best approximation:
                  Code:
                  TYPE SALE_UPDATE BYTE
                     btime(1 TO 3) AS BYTE        
                     format AS BYTE   
                     seq AS LONG
                     value AS LONG           
                     volume AS LONG          
                     saleCode AS ASCIIZ *1
                  END TYPE
                  If this does not work, exactly how are the members following "btime" becoming de-synchronized?

                  Note that the member btime(1 TO 3) AS BYTE creates a member array of btime(1), btime(2), and btime(3).

                  However, in your declaration btime(2) AS BYTE there are still 3 subscripts in that member array: btime(0), btime(1) and btime(2).

                  IOW, maybe your translation is ok, but you are missing the 1st subscript whose index is zero?

                  ------------------
                  Lance
                  PowerBASIC Support
                  mailto:[email protected][email protected]</A>
                  Lance
                  mailto:[email protected]

                  Comment


                  • #10
                    Code:
                       saleCode AS BYTE

                    ------------------
                    Tom Hanlin
                    PowerBASIC Staff

                    Comment


                    • #11
                      Well, I am embarrassed!

                      It seems that bugs are always in the simple things.... For some reason beyond explanation I had failed to look at byte 0 of the array (time)! I looked there and, lo and behold, there was the hour! And, I know that arrays normally start at 0, too..... oops!

                      Tom, I haven't looked at the salecode yet. I'll check into that.

                      Thanks, again, guys! Another pair of eyes helps us see through our blind spots.

                      Dale

                      ------------------

                      Comment

                      Working...
                      X