Announcement

Collapse
No announcement yet.

BTRCALL versus BTRV

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

  • Mike Doty
    replied
    Sounds like your TYPE is not found before the DIM or LOCAL.
    Place the #INCLUDE statement at the very top and be sure the TYPE
    statement(s) are first in the include file.

    Leave a comment:


  • Mike Doty
    replied
    Code:
    'VB6.
    Option Explicit
    Private Type Type1
      F10SCON   As String * 10
      F10SNOPL  As String * 8
      F10NOIN   As String * 8
      F10SLRNU  As Integer
      F10SPACK  As String * 8
      F10SINVC  As String * 8
    End Type
    Private Type Type2
      F10SCON   As String * 10
      F10SNOPL  As Double
      F10NOIN   As Double
      F10SLRNU  As Integer
      F10SPACK  As Double
      F10SINVC  As Double
    End Type
    Function PBMAIN() As Long
      Dim t1 As Type1
      Dim t2 As Type2
      t1.F10SCON = "This works"
      Print t1.F10SCON
      Print WaitKey
    End Function
    Private Sub Form_Load()
      Me.AutoRedraw = True  'allow print
      Cls
      PBMAIN
    End Sub
    Function WaitKey() As String
      WaitKey = "Simulated WaitKey"
    End Function

    Leave a comment:


  • Mike Doty
    replied
    The only thing I can think of is "PRIVATE TYPE" if used in the main module of VB.
    Also, VB only uses DIM (no LOCAL.)
    Code:
    #COMPILE EXE
    #DIM ALL
    TYPE Type1
      F10SCON   AS STRING * 10
      F10SNOPL  AS STRING * 8
      F10NOIN   AS STRING * 8
      F10SLRNU  AS INTEGER
      F10SPACK  AS STRING * 8
      F10SINVC  AS STRING * 8
    END TYPE
    TYPE Type2
      F10SCON   AS STRING * 10
      F10SNOPL  AS DOUBLE
      F10NOIN   AS DOUBLE
      F10SLRNU  AS INTEGER
      F10SPACK  AS DOUBLE
      F10SINVC  AS DOUBLE
    END TYPE
    FUNCTION PBMAIN AS LONG
      LOCAL t1 AS Type1
      LOCAL t2 AS Type2
      t1.F10SCON = "This works"
      PRINT t1.F10SCON
      WAITKEY$
    END FUNCTION

    Leave a comment:


  • Roy Bauer
    replied
    Hi Mike. In response to your question, yes, I put in that conversion rountine, read the data, converted it, and it worked just fine. Thanks for that code.

    I do, however, have a pretty basic question for you. I am using the PBCC. When I put the TYPE statements in to identify the input and the output record definitions, the compiler doesnt seem to recognize the TYPE definitions. When I compile the Program it tells me that I need a TYPE identifier (Like a # or $, or !) for the variables that I named in the TYPE statement. (these Variables are in an INCLUDE, would that make a difference). Also, the compiler would not let me use udt1.f10scon, for example giving me an error that the period was invalid.

    This may be the difference between VB and PBCC?

    I horsed around with the variable names and got it to read and convert, but not by using the TYPE statement. I would prefer to use TYPE as then I can convert and strore these records as defined by the TYPE statement. If not, I probably have to convert them back to strings per the code that was sent.

    Roy

    Leave a comment:


  • Michael Mattias
    replied
    If I read my data in and convert it, when I write it back I assume it will write back the converted data so that once I have done this conversion, I shouldnt have to do it again??
    Um, when you read it again, how will you know it has/has not been converted? It's just 64 bits of data, there's nothing in it that tells you it has has/not been converted.

    Let's assume for the moment those DOUBLEs are in MBF format.

    This gives you have TWO (count 'em, two, deux, dos) choices.

    A. You keep the data on disk in MBF, in which case you convert to IEEE every time you read, and back to MBF every time you write

    B. You want the data on disk in IEEE format, in which case you write a one-time file conversion program to do so.

    First step though, is to determine "if" the data currently on disk is in fact in MBF format. If it is, then you make your choice and proceed accordingly. If it isn't, then you have to figure out what it really is. (But based on prior postings, five bucks says it IS mbf).

    MCM

    Leave a comment:


  • Mike Doty
    replied
    I updated posting above with a method.
    Did the 8-byte strings convert to doubles?
    Last edited by Mike Doty; 22 Dec 2008, 11:11 PM.

    Leave a comment:


  • Mike Doty
    replied
    No, you won't have to do it again. Backup original file as this updates instead of creating a new file.
    Read with UDT1 with STRING * 8 and update to UDT2 with DOUBLE.
    This method STEPS through the file and UPDATES each record.
    Code:
    #COMPILE EXE
    #DIM ALL
    %Update    = 3
    %StepNext  = 24
    %StepFirst = 33
    GLOBAL gBlock1 AS ASCIIZ * 128
    TYPE Type1
      F10SCON   AS STRING * 10
      F10SNOPL  AS STRING * 8
      F10NOIN   AS STRING * 8
      F10SLRNU  AS INTEGER
      F10SPACK  AS STRING * 8
      F10SINVC  AS STRING * 8
    END TYPE
    TYPE Type2
      F10SCON   AS STRING * 10
      F10SNOPL  AS DOUBLE
      F10NOIN   AS DOUBLE
      F10SLRNU  AS INTEGER
      F10SPACK  AS DOUBLE
      F10SINVC  AS DOUBLE
    END TYPE
    FUNCTION PBMAIN () AS LONG
      LOCAL result AS INTEGER
      LOCAL udt1 AS Type1
      LOCAL udt2 AS Type2
      LOCAL zKeyBuffer AS ASCIIZ * 64
      LOCAL s      AS STRING
      LOCAL d      AS DOUBLE
     
      'Get btrieve using UDT1
      result = BTRCALL(%StepFirst, gBlock1, udt1, LEN(udt1), zKeyBuffer, 64, 0)
      DO WHILE result = 0
        udt2.F10SCON = udt1.F10SCON
        s = udt1.F10SNOPL: d = cvmd(s):  udt2.F10SNOPL   = d
        s = udt1.F10NOIN : d = cvmd(s):  udt2.F10NOIN    = d
        udt2.F10SLRNU  = udt1.F10SLRNU
        s = udt1.F10SPACK : d= cvmd(s):  udt2.F10SPACK   = d
        s = udt1.F10SINVC  : d= cvmd(s):  udt2.F10SINVC  = d
     
        'Update file with new UDT2
        result = BTRCALL(%Update, gBlock1, udt2, LEN(udt2), zKeyBuffer, 64, 0)
     
        'Step next
        result = BTRCALL(%StepNext, gBlock1, udt1, LEN(udt1), zKeyBuffer, 64, 0)
      LOOP
      WAITKEY$
    END FUNCTION
    FUNCTION cvmd (x AS STRING) AS DOUBLE
        LOCAL outp AS DOUBLE
      ! mov EBX, x              ; EBX = string handle
      ! mov EBX, DWORD PTR [EBX]; EBX = address of string data
      ! mov  AX,[EBX+06]        ;load AX  :DX:BX  :DI with the four MBF words
      ! mov  DX,[EBX+04]
      ! mov  DI,[EBX]
      ! mov  BX,[EBX+02]
      ! mov  ECX,3              ;the number of bits to shift
    Do1:
      ! shr  AL,1               ;shift the mantissa right one place
      ! rcr  DX,1
      ! rcr  BX,1
      ! rcr  DI,1
      ! loop Do1
      ! or   AH,AH              ;is the exponent zero?
      ! jnz  F1                 ;no, continue
      ! mov  AL,AH              ;yes, assign all zeros
      ! mov  Outp,AX            ;store the lower three words here
      ! mov  Outp[02],AX        ;
      ! mov  Outp[04],AX        ;
      ! jmp  Zero               ;and skip ahead to assign the highest word
    F1:
      ! mov  Outp, DI           ;store the lower three words
      ! mov  Outp[02],BX
      ! mov  Outp[04],DX
      ! mov  DL,AL              ;swap the sign and exponent bits
      ! mov  AL,AH
      ! sub  AH,AH
      ! add  AX,&H37E           ;adjust the exponent bias
      ! test DL,&H10            ;is the sign bit set?
      ! jz   F2                 ;no, skip ahead
      ! or   AH,8               ;yes, so set the IEEE sign bit too
    F2:
      ! mov  CL,4
      ! shl  AX,CL
      ! and  DL,&H0F
      ! or   AL,DL
    Zero:
      ! mov  Outp[06],AX        ;store the result
        FUNCTION = outp
    END FUNCTION
    'simulate Btrieve DLL
    FUNCTION BTRCALL  (BYVAL Op AS INTEGER,              _
                       gBlock1 AS ASCIIZ,                _
                       udt1 AS Type1,                    _
                       DataLength AS INTEGER,            _
                       zKeyBuffer AS ASCIIZ,             _
                       BYVAL Keylength AS INTEGER, _
                       BYVAL KeyNumber AS INTEGER) AS INTEGER
    END FUNCTION
    Last edited by Mike Doty; 22 Dec 2008, 11:15 PM.

    Leave a comment:


  • Roy Bauer
    replied
    Thanks guy. I will give this a shot. One question. If I read my data in and convert it, when I write it back I assume it will write back the converted data so that once I have done this conversion, I shouldnt have to do it again?? Merry Christmans and Happy Holidays.
    Roy

    Leave a comment:


  • Mike Doty
    replied
    Try this

    Code:
    #COMPILE EXE
    #DIM ALL
    TYPE MyRecordType
      F10SCON   AS STRING * 10
      F10SNOPL  AS STRING * 8
      F10NOIN   AS STRING * 8
      F10SLRNU  AS INTEGER
      F10SPACK  AS STRING * 8
      F10SINVC  AS STRING * 8
    END TYPE
    FUNCTION PBMAIN () AS LONG
      LOCAL Record AS MyRecordType
      LOCAL s      AS STRING
      LOCAL D      AS DOUBLE
      'Get Btrieve record
      s = Record.F10SNOPL
      d = cvmd(s)
      ? s
      WAITKEY$
    END FUNCTION
    FUNCTION cvmd (x AS STRING) AS DOUBLE
        LOCAL outp AS DOUBLE
      ! mov EBX, x              ; EBX = string handle
      ! mov EBX, DWORD PTR [EBX]; EBX = address of string data
      ! mov  AX,[EBX+06]        ;load AX  :DX:BX  :DI with the four MBF words
      ! mov  DX,[EBX+04]
      ! mov  DI,[EBX]
      ! mov  BX,[EBX+02]
      ! mov  ECX,3              ;the number of bits to shift
    Do1:
      ! shr  AL,1               ;shift the mantissa right one place
      ! rcr  DX,1
      ! rcr  BX,1
      ! rcr  DI,1
      ! loop Do1
      ! or   AH,AH              ;is the exponent zero?
      ! jnz  F1                 ;no, continue
      ! mov  AL,AH              ;yes, assign all zeros
      ! mov  Outp,AX            ;store the lower three words here
      ! mov  Outp[02],AX        ;
      ! mov  Outp[04],AX        ;
      ! jmp  Zero               ;and skip ahead to assign the highest word
    F1:
      ! mov  Outp, DI           ;store the lower three words
      ! mov  Outp[02],BX
      ! mov  Outp[04],DX
      ! mov  DL,AL              ;swap the sign and exponent bits
      ! mov  AL,AH
      ! sub  AH,AH
      ! add  AX,&H37E           ;adjust the exponent bias
      ! test DL,&H10            ;is the sign bit set?
      ! jz   F2                 ;no, skip ahead
      ! or   AH,8               ;yes, so set the IEEE sign bit too
    F2:
      ! mov  CL,4
      ! shl  AX,CL
      ! and  DL,&H0F
      ! or   AL,DL
    Zero:
      ! mov  Outp[06],AX        ;store the result
        FUNCTION = outp
    END FUNCTION


    Code:
    '*********** CVSMBF.ASM - PDQ replacement for BASIC's B$MCVS routine
    'code by Ethan Winer using code derived from Cobb's Inside
    'Assembler newsletter (after fixing the code to handle zero properly!)
    'converted to PB/DLL 5.0 by Dave Navarro, Jr. (8/25/97)
    ' Corrected from post from Matthew Suter (11/09/99)
    ' Updated for PB/Win 7.0 by Tom Hanlin (07/03/02)
    $COMPILE DLL
    FUNCTION CVMS (x AS STRING) EXPORT AS SINGLE
      LOCAL outp AS SINGLE
      ! mov EBX, x              ; EBX = string handle
      ! mov EBX, DWord Ptr [EBX] ; EBX = address of string data
      ! mov AX, Word Ptr [EBX]  ; grab the low word
      ! mov outp, AX            ; store it in the output
      ! mov AX, [EBX+2]         ; now grab the high word
      ! or  AH, AH              ; is the exponent zero?
      ! jz  notzero             ;
      ! sub AH, 2               ; fix the exponent
      ! rcl AL, 1               ; slide the sign bit into the carry flag
      ! rcr AX, 1               ; and then slide the sign and exponent into place
    NotZero:
      ! mov outp[2], AX         ; store that in the output too
      FUNCTION = outp
    END FUNCTION
    '******** MKSMBF.ASM - PDQ replacement for BASIC's B$FMSF routine
    'by Ethan Winer using code derived from Cobb's Inside Assembler newsletter
    '(after fixing the code to handle zero properly!)
    'converted to PB/DLL 5.0 by Dave Navarro, Jr. (8/25/97)
    FUNCTION MKMS (BYVAL s AS SINGLE) EXPORT AS STRING
      LOCAL outp AS STRING PTR * 4
      ! mov AX, s[2]        ; convert the number to MBF in place on the stack
      ! rcl AX, 1           ; slide the sign bit into the carry flag
      ! rcr AL, 1           ; and then into the correct bit position for MBF
      ! or  AX, AX          ; is the exponent zero?
      ! je  itszero         ; yes, skip ahead
      ! add AH, 2           ; no, adjust the exponent bias
    itszero:
      ! mov  s[2], AX       ; copy the adjusted value back onto the stack
      outp = VARPTR(s)      '
      FUNCTION = @outp      '
    END FUNCTION
    '******** CVDMBF.ASM - PDQ replacement for BASIC's B$FMSF routine
    'by Ethan Winer using code derived from Cobb's Inside Assembler newsletter
    '(after fixing the code to handle zero properly!)
    'converted to PB/DLL 5.0 by Dave Navarro, Jr. (6/29/98)
    ' Corrected from post by Thomas G. Hanlin III (8/7/00)
    FUNCTION CVMD (x AS STRING) EXPORT AS DOUBLE
      LOCAL outp AS DOUBLE
      ! mov EBX, x               ; EBX = string handle
      ! mov EBX, DWORD PTR [EBX] ; EBX = address of string data
      ! mov  AX,[EBX+06]        ;load AX:DX:BX:DI with the four MBF words
      ! mov  DX,[EBX+04]
      ! mov  DI,[EBX]
      ! mov  BX,[EBX+02]
      ! mov  ECX,3               ;the number of bits to shift
    Do1:
      ! shr  AL,1               ;shift the mantissa right one place
      ! rcr  DX,1
      ! rcr  BX,1
      ! rcr  DI,1
      ! loop Do1
      ! or   AH,AH            ;is the exponent zero?
      ! jnz  F1               ;no, continue
      ! mov  AL,AH            ;yes, assign all zeros
      ! mov  Outp,AX          ;store the lower three words here
      ! mov  Outp[02],AX      ;
      ! mov  Outp[04],AX      ;
      ! jmp  Zero             ;and skip ahead to assign the highest word
    F1:
      ! mov  Outp, DI         ;store the lower three words
      ! mov  Outp[02],BX
      ! mov  Outp[04],DX
      ! mov  DL,AL              ;swap the sign and exponent bits
      ! mov  AL,AH
      ! sub  AH,AH
      ! add  AX,&H37E           ;adjust the exponent bias
      ! test DL,&H10            ;is the sign bit set?
      ! jz   F2                 ;no, skip ahead
      ! or   AH,8               ;yes, so set the IEEE sign bit too
    F2:
      ! mov  CL,4
      ! shl  AX,CL
      ! and  DL,&H0F
      ! or   AL,DL
    Zero:
      ! mov  Outp[06],AX      ;store the result
      FUNCTION = outp
    END FUNCTION
    '******** MKDMBF.ASM - PDQ replacement for BASIC's B$FMDF routine
    'by Ethan Winer using code derived from Cobb's Inside Assembler newsletter
    '(after fixing the code to handle zero properly!)
    'converted to PB/DLL 5.0 by Dave Navarro, Jr. (6/29/98)
    FUNCTION MKMD (BYVAL d AS DOUBLE) EXPORT AS STRING
      LOCAL outp AS STRING PTR * 8
      ! mov  AX,Word Ptr d[6]       ;copy the high word into AX
      ! mov  DX,AX          ;keep a copy for later
      ! mov  CL,4           ;number of bits to shift
      ! shr  AX,CL          ;shift 'em good
      ! and  AX,&H7FF       ;mask off the sign bit
      ! jz   F3             ;if the exponent is zero skip over
      ! sub  AX,&H37E       ;adjust the exponent bias only if non-zero!
    F3:
      ! mov  Byte Ptr d[7],AL       ;store just the exponent
      ! mov  AX,DX          ;load the copy of the high word into AX again
      ! mov  SI,Word Ptr d[0]       ;and then load the rest into DX:BX:SI
      ! mov  BX,Word Ptr d[2]
      ! mov  DX,Word Ptr d[4]
      ! mov  ECX,3           ;the number of times to shift bits
    F4:
      ! shl  SI,1           ;shift the mantissa left one place
      ! rcl  BX,1
      ! rcl  DX,1
      ! rcl  AL,1
      ! loop F4
      ! shl  AX,1           ;shift the sign bit into the Carry flag
      ! rcr  AL,1
      ! mov  Word Ptr d[0],SI       ;store the output back onto the stack
      ! mov  Word Ptr d[2],BX
      ! mov  Word Ptr d[4],DX
      ! mov  Byte Ptr d[6],AL
      outp = VARPTR(d)
      FUNCTION = @outp
    END FUNCTION
    Last edited by Mike Doty; 22 Dec 2008, 08:34 PM.

    Leave a comment:


  • Mike Doty
    replied
    As Michael is saying and don't use DWORD FILL.
    Hopefully, you downloaded msbf.zip from post #46 above.
    Wait, the UDT shouldn't convert the data. I'll repost below.
    Last edited by Mike Doty; 22 Dec 2008, 08:25 PM.

    Leave a comment:


  • Michael Mattias
    replied
    Looks like i have some kind of double word conversion issue. I am going to try DWORD FILL again as I made a bunch of changes since I tried that last
    Don't. What is the SIZEOF(record) now, with BYTE (default) alignment? It was 44, which is your record size. So FILL is going to do nothing except perhaps make your record the wrong size.

    Did you try MBF on those 'DOUBLE' UDT members? (Code not shown.)

    Redefine as 'STRING * 8' and pass that string to the conversion function to which you were provided a link.

    That the integer member of the UDT following the alleged DOUBLEs came out correctly tells you the problem is definitely with the conversion of the 'DOUBLEs' or whatever they are, and not with aligment of data within the UDT.



    MCM

    Leave a comment:


  • Roy Bauer
    replied
    Based on what you are saying, I think conversion is the issues.

    Here are what the values should be
    F10SCON AS String * 10 "CONTROLREC" THis comes out OK
    F10SNOPL AS DOUBLE Should be 475 Prints out as -2.92762750482235E-263
    F10SNOIN AS DOUBLE Should be 271915 Prints out as -4.70728462903235E-217
    F10SLRNU AS INTEGER Should be 482 Prints out as 482. This is OK
    F10SLPAC AS DOUBLE Should be 367907 Prints Out as -3.56115449393892E-216
    F10SLINV AS DOUBLE Should be 367875 Prints out as -3.55832164675155E-216

    Interesting that the Integer number is coming out OK.

    Looks like i have some kind of double word conversion issue. I am going to try DWORD FILL again as I made a bunch of changes since I tried that last.

    Leave a comment:


  • Mike Doty
    replied
    http://www.powerbasic.com/support/pb...ht=convert+mbf
    Albert Richheimer placed a link to a library in msbf.zip
    Last edited by Mike Doty; 22 Dec 2008, 09:41 AM.

    Leave a comment:


  • Michael Mattias
    replied
    If that's QuickBasic 3, I know those DOUBLEs are MBF format, not IEEE

    There has GOT to be a "convert MBF" function here somewhere. Search on "MBF" or "Microsoft Binary Format"

    Don't worry about byte alignment. That should not have any meaning at all under Btrieve for Win/32. Byte alignment was used by 16-bit code to allow use of integral paragraphs in the segment:address format used by MS-DOS and to facilitate "linearness" across 64K chunks of memory. (cf PB-DOS "DIM HUGE")

    Leave a comment:


  • Mike Doty
    replied
    Post a record with what the values should be so we can examine it.
    Example ASCII values: 0 0 0 0 0 0 98 137 should be what value?
    I would guess the file was in MBF format.
    Also, did you try DWORD FILL (just in case?)
    Just curious, what is the largest number used? If money, LONGS may be easier in the future.
    Last edited by Mike Doty; 22 Dec 2008, 09:24 AM.

    Leave a comment:


  • Roy Bauer
    replied
    Hi Guys. i appreciate your input. Peter, yes I have that thread. I seem to be able to make BTRIEVE Calls OK. The file OPENS without error (Status 0), and I can do a GETGE (Get Greater Than or Equal to) with a return status of 0, and a CLOSE OK.
    So I think all your help has gotten me to the point where BTRIEVE is not the issue.

    My issue appears to be that the numeric data will not convert (see my note above) like it does in the Old Version. I am guessing that my numeric data is at some older version of QB that creates this problem, or my buffer is not on a correct byte boundary. All this seems odd to me because of the way I orginally handled the data was to convert the numberic to on long string using MID$ and MKx, and write the string, then read back the string and convert the string segments into variables using CVx. In todays enviornment, not that efficient but that was how it was in the early days of PC's.

    Anyone have any other thoughts about it?

    If it is a data conversion problem, (I think this code was compiles on QB-Version 3, Is there anyone with information on how I can convert these numberic fields?

    By the way, I am on an NT Network using Pervasive SQL 2000i

    Leave a comment:


  • Michael Mattias
    replied
    The difference is the old CVD converts the data to a double byte variable, while the new data CVD gives a -2.nnnnnnnnnnn Ennn.

    Could this be a problem with data offset, or a difference in how PB uses CVD?
    It could just be a difference in how you display the variable after you "CVD" it.

    -2.nnnnnnnEmmm would be something like -2<mmm zeroes>. nnnnnnnn

    Code not shown. Reference data not shown. Tunnel not shown, leave alone light at end thereof.

    And if you are coming off a MICROSOFT basic (not shown), you may be encountering differences between Microsoft Binary Format (MBF) and IEEE double-precision format in that conversion.

    Leave a comment:


  • Peter Lameijn
    replied
    Roy,

    Have you seen this thread (from long ago) where I solved some btrieve problems? I used btrieve 5/6/7 a lot in the past, but haven't used it for year now (since we stepped away from NetWare servers... )

    Leave a comment:


  • Mike Doty
    replied
    That was only an example finding a value with a binary key of 1.
    Don't know about the double precision values, sorry.
    Sounds like you are getting close.

    Leave a comment:


  • Roy Bauer
    replied
    Hi again Mike. I will work on this tomorrow. Thanks for your effort. The only thing I did not understand in this line of code was the "ZkeyBuffer = MKL$(1)" What/Where is MKL$(1) used?

    On another note. I ran the old program and printed out the results of the old returned data string and it is EXACTLY the same as the new string, with the same characters in the same position, (Same data in both .DAT files). The difference is the old CVD converts the data to a double byte variable, while the new data CVD gives a -2.nnnnnnnnnnn Ennn.

    Could this be a problem with data offset, or a difference in how PB uses CVD?

    ROy

    Leave a comment:

Working...
X