Announcement

Collapse
No announcement yet.

VB.Net and Btrieve (Pervasive PSQL)

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

  • VB.Net and Btrieve (Pervasive PSQL)

    Anybody ever written VB.Net code with the BTRCALL Function. VB.Net doesn't support the "As ANY" variable definition in the BTRCALL Function. In looking at the example provided by Pervasive, it appears that they have to use the MARSHALL AS function to convert data from Physical (Btrieve) Record to Application (.Net) Record and that the Btrieve data are stored in BYTE Format. (i. e. numeric variables converted to bytes. ). They have a bunch of comments about "moving data between unmanaged memory blocks to Managed Memory Block, and vise versa.

    Did I interpret the example correctly, and is byte-to-byte conversion the only way VB.Net and BTRCALL can work together on data Records?:confused2:

  • #2
    I have an working ppcc example, where i use the as any declaration. I also have found an old vb6 class example with following declaration:

    Private Declare Function btrcall Lib "wbtrv32.dll" Alias "BTRCALL" (ByVal OP%, ByVal Pb$, ByVal Db$, Dl&, ByVal Kb$, ByVal Kl%, ByVal Kn%) As Long
    My knowledge in vb.net is not good enough to know, how the data type are internally stored.
    Why do you use still the oldest interface to btrieve?

    Reinhard

    Comment


    • #3
      Your response

      Thanks for your response. You are correct that vb 6 allows the use of "ANY" in the Declare, but VB.Net doesn't allow it.. Something to do with managed versus unmanaged memory.

      You last statement about using the oldest interface was of interest to me. I am using PSQL 11. (Pervasive). I assumed that I was using up to date btrieve. What is the alternative you are thinking about?

      Comment


      • #4
        I think you can use different interfaces. Today the most used interface will be the odbc or oledb driver; in this way you can use the tables inside access and maybe combine both products. To use this, you have to have ddf files for your data.
        In an vb6 application i am using btrvpro ocx files, but i never tested this interface if it works with vb.net. This product was from 1998; i think, this firm does not exist today.
        And there exists an second set of ocx interfaces from pervasive, but i never used it.
        Greetings
        Reinhard

        Comment


        • #5
          I also have found an old vb6 class example with following declaration:
          Code:
          Private Declare Function btrcall Lib "wbtrv32.dll" Alias "BTRCALL" (ByVal OP%, ByVal Pb$, ByVal Db$, Dl&, ByVal Kb$, ByVal Kl%, ByVal Kn%) As Long
          My knowledge in vb.net is not good enough to know, how the data type are internally stored.
          You really should use your Btrieve doc and create your own DECLARE from that. I'm pretty sure using "an old vb6 class example" is just asking for trouble and knowing how VB.NET stores data internally is irrelevant to programming in PowerBASIC.



          MCM
          Michael Mattias
          Tal Systems Inc. (retired)
          Racine WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            Roy,
            Can you call the exported BTRIEVE in minimal.dll from VB.NET?
            Create minimal.dll
            Code:
            #DIM ALL 'DataBlockType pass a TYPE variable
            #COMPILE DLL  "minimal.dll"
            '-------------------------------------------
            DECLARE FUNCTION BTRCALL LIB "wbtrv32.dll" _
             (BYVAL OP               AS INTEGER, _
                    zDataBlock       AS ASCIIZ,  _
                    DataBlockType    AS ANY,     _
                    DataLength       AS INTEGER, _
                    zKeyBuffer       AS ASCIIZ,  _
                    BYVAL KeyLength  AS INTEGER, _
                    BYVAL KeyNumber  AS INTEGER) AS INTEGER
            '------------------------------------------
            TYPE ClientType
              number AS INTEGER
            END TYPE
            '------------------------------------------
            FUNCTION Btrieve(Op             AS INTEGER,  _
                             PositionBlock  AS ASCIIZ,  _
                             DataBlockType  AS ClientType, _
                             DataLength     AS INTEGER,  _
                             zKeyBuffer     AS ASCIIZ,  _
                             KeyLength      AS INTEGER, _  _
                             KeyNumber      AS INTEGER) EXPORT AS INTEGER
              LOCAL result AS INTEGER
              ? USING$("Op # datalength # keylength # Result #",op,datalength,keylength,result),,"Before"
              result=BTRCALL(op,PositionBlock,DataBlockType,datalength,zkeybuffer,keylength,keyNumber)
              ? USING$("Op # datalength # keylength # Result #",op,datalength,keylength,result),,"After"
              FUNCTION = result
            END FUNCTION
            '------------------------------------------
            FUNCTION PBMAIN () AS LONG
              LOCAL op,datalength,KeyLength,KeyNumber,result AS INTEGER
              LOCAL PositionBlock AS ASCIIZ * 129
              LOCAL zKeyBuffer    AS ASCIIZ * 65
              LOCAL c AS ClientType
              op = 200
              zKeyBuffer = "file1.dat"
              keynumber = -64
              result = Btrieve(op,PositionBlock,c,DataLength,zKeyBuffer,KeyLength,keynumber)
              op = 12
              DataLength = 512
              keynumber = 2
              result = Btrieve(op,PositionBlock,c,DataLength,zKeyBuffer,KeyLength,KeyNumber)
             END FUNCTION
            Call BTRIEVE in minimal.dll
            Code:
            #COMPILE EXE
            #DIM ALL
             
            TYPE ClientType   'filename FILE1.DAT
              number    AS INTEGER
              phone     AS STRING * 7
              lastname  AS STRING * 20
              firstname AS STRING * 20
              dummy     AS STRING * 203-51
            END TYPE
             
            DECLARE FUNCTION BTRIEVE LIB "minimal.dll" _
                             (Op         AS INTEGER, _
                             ClientBlock AS ASCIIZ, _
                             DataBlock   AS ClientType, _
                             DataLength  AS INTEGER, _
                             zKeyBuffer  AS ASCIIZ, _
                             KeyLength   AS INTEGER, _
                             KeyNumber   AS INTEGER) AS INTEGER
             
            FUNCTION PBMAIN () AS LONG
              LOCAL Op,DataLength,KeyLength,KeyNumber AS INTEGER
              LOCAL PositionBlock AS ASCIIZ * 129
              LOCAL zKeyBuffer    AS ASCIIZ * 65
              LOCAL result AS INTEGER
              LOCAL c AS ClientType
              Op = 200
              zKeyBuffer = "file1.dat"
              KeyLength = 64
              KeyNumber = -64
              result = Btrieve(Op,PositionBlock,c,DataLength,zKeyBuffer,KeyLength,KeyNumber)
              Op = 12
              DataLength = 203
              KeyLength =  64
              KeyNumber = 2
              result = Btrieve(Op,Positionblock,c, DataLength,zKeyBuffer,KeyLength,KeyNumber)
              ? c.lastname
            END FUNCTION
            Last edited by Mike Doty; 17 Jun 2015, 05:40 PM.
            How long is an idea? Write it down.

            Comment


            • #7
              Added the CVI,MKI$, ... conversion functions.
              Useful if a TYPE is not used or until alignment issues are fixed.
              Any 2-byte, 4-byte binary fields can be string * 2 or string * 4
              and the CV function used.

              Also defined the Btrieve op codes.

              Code:
              #DIM ALL 'DataBlockType pass a TYPE variable
              #COMPILE DLL "minimal"
              #EXPORT VBCVI,VBCVS,VBCVL,VBCVD,VBMKI,VBMKS,VBMKL,VBMKD
              %ShareMode = -64
              %b_open      = 200:  %b_close      =  1:  %b_insert    =  2:   %b_update       =  3
              %b_delete    =   4:  %b_equal      =  5:  %b_next      =  6:   %b_previous     =  7
              %b_greater   =   8:  %b_ge         =  9:  %b_less      = 10:   %b_leE          = 11
              %b_first     =  12:  %b_last       = 13:  %b_create    = 14:   %b_stat         = 15
              %b_begintran =  19:  %b_endtran    = 20:  %b_aborttran = 21:   %b_position     = 22
              %b_direct    =  23:  %b_StepNext   = 24:  %b_stop      = 25:   %b_unlock       = 27
              %b_reset     =  28:  %b_StepFirst  = 33:  %b_StepLast  = 34:   %b_StepPrevious = 35
              '-------------------------------------------
              DECLARE FUNCTION BTRCALL LIB "wbtrv32.dll" _
               (BYVAL OP               AS INTEGER, _
                      zDataBlock       AS ASCIIZ,  _
                      DataBlockType    AS ANY,     _
                      DataLength       AS INTEGER, _
                      zKeyBuffer       AS ASCIIZ,  _
                      BYVAL KeyLength  AS INTEGER, _
                      BYVAL KeyNumber  AS INTEGER) AS INTEGER
              '------------------------------------------
              TYPE ClientType
                dummy AS STRING * 203
              END TYPE
              '------------------------------------------
              FUNCTION Btrieve(Op             AS INTEGER,  _
                               PositionBlock  AS ASCIIZ,  _
                               DataBlockType  AS ClientType, _
                               DataLength     AS INTEGER,  _
                               zKeyBuffer     AS ASCIIZ,  _
                               KeyLength      AS INTEGER, _  _
                               KeyNumber      AS INTEGER) EXPORT AS INTEGER
                LOCAL result AS INTEGER
                '? USING$("Op # datalength # keylength # Result #",op,datalength,keylength,result),,"Before"
                result=BTRCALL(op,PositionBlock,DataBlockType,datalength,zkeybuffer,keylength,keyNumber)
                '? USING$("Op # datalength # keylength # Result #",op,datalength,keylength,result),,"After 1"
                FUNCTION = result
              END FUNCTION
              '------------------------------------------
              FUNCTION PBMAIN () AS LONG
                LOCAL op,datalength,KeyLength,KeyNumber,result AS INTEGER
                LOCAL PositionBlock AS ASCIIZ * 129
                LOCAL zKeyBuffer    AS ASCIIZ * 65
                LOCAL c AS ClientType
                 op = 200
                zKeyBuffer = "file1.dat"
                keynumber = -64
                result = Btrieve(op,PositionBlock,c,DataLength,zKeyBuffer,KeyLength,keynumber)
                 op = 12
                DataLength = 512
                keynumber = 2
                result = Btrieve(op,PositionBlock,c,DataLength,zKeyBuffer,KeyLength,KeyNumber)
               END FUNCTION
               
              FUNCTION VBCVI(sInteger AS STRING) EXPORT AS INTEGER
                FUNCTION = CVI(sInteger)
              END FUNCTION
              FUNCTION VBCVS(sSingle AS STRING)  EXPORT AS SINGLE
                FUNCTION = CVS(sSingle)
              END FUNCTION
              FUNCTION VBCVL(sLONG AS STRING)    EXPORT AS LONG
                FUNCTION = CVL(sLong)
              END FUNCTION
              FUNCTION VBCVD(sDouble AS STRING)  EXPORT AS DOUBLE
                FUNCTION = CVD(sDouble)
              END FUNCTION
               FUNCTION VBMKI(MyInteger AS INTEGER) EXPORT AS STRING
                FUNCTION = MKI$(MyInteger)
              END FUNCTION
              FUNCTION VBMKS(MySingle AS SINGLE)   EXPORT AS STRING
                FUNCTION = MKS$(MySingle)
              END FUNCTION
              FUNCTION VBMKL(MyLong AS LONG)       EXPORT AS STRING
                FUNCTION = MKL$(MyLong)
              END FUNCTION
              FUNCTION VBMKD(MyDouble AS DOUBLE)   EXPORT AS STRING
                FUNCTION = MKD$(MyDouble)
              END FUNCTION
              How long is an idea? Write it down.

              Comment


              • #8
                This isn't VB.NET, but VB6 which might help.
                In this program any INTEGER or LONG is STRING *2 or STRING * 4
                and the CVI or CVL is used until the TYPE is correctly aligned.
                Code:
                Option Explicit
                Private Declare Function CVI Lib "minimal.dll" Alias "VBCVI" (s As String) As Integer
                Private Declare Function CVS Lib "minimal.dll" Alias "VBCVS" (s As String) As Single
                Private Declare Function CVL Lib "minimal.dll" Alias "VBCVL" (s As String) As Long
                Private Declare Function CVD Lib "minimal.dll" Alias "VBCVD" (s As String) As Double
                Private Declare Function MKI Lib "minimal.dll" Alias "VBMKI" (number As Integer) As String
                Private Declare Function MKS Lib "minimal.dll" Alias "VBMKS" (number As Single) As String
                Private Declare Function MKL Lib "minimal.dll" Alias "VBMKL" (number As Long) As String
                Private Declare Function MKD Lib "minimal.dll" Alias "VBMKD" (number As Double) As String
                 
                Private Type ClientType     'file1.dat
                  number As String * 2       '   1      2
                  HomePhone As String * 7    '   3      9
                  LastName As String * 20    '  10     29
                  FirstName As String * 20   '  30     49
                  ZIP As String * 10         '  50     59
                  ID As String * 11          '  60     70
                  BAL As String * 4          '  71     74
                  Address1 As String * 30    '  75    104
                  Address2 As String * 30    ' 105    134
                  City As String * 20        ' 135    154
                  STATE As String * 2        ' 155    156
                  DR As String * 1           ' 157    157
                  WorkPhone As String * 7    ' 158    164
                  NumberOfPets As String * 2 ' 165    166
                  TotalCredits As String * 4 ' 167    170
                  LastPaymentAmt As String * 4 ' 171    174
                  LastPaymentDate As String * 2 ' 175    176
                  Discount As String * 2     ' 177    178
                  Area1 As String * 3        ' 179    181
                  Area2 As String * 3        ' 182    184
                  Group As String * 8        ' 185    192
                  crCode As String * 4       ' 193    196
                  DateAdded As String * 2    ' 197    198
                  ClientFlag As String * 1   ' 199    199
                  TaxRate As String * 4      ' 200    203  
                End Type
                 
                Private PositionBlock As String * 128
                Private zKeyBuffer As String * 64
                 
                 Private Declare Function BTRIEVE Lib "minimal.dll" ( _
                    op As Integer, _
                    ByVal PositionBlock As String, _
                    Datablock As ClientType, _
                    datalength As Integer, _
                    ByVal zKeyBuffer As String, _
                    keylength As Integer, _
                    keynumber As Integer) As Integer
                    
                 Private Sub Command1_Click(Index As Integer)
                  Dim op, datalength, keylength, keynumber, result As Integer
                  Dim zKeyBuffer As String * 64
                  Dim c As ClientType
                    
                  Select Case Index
                    Case 0
                      op = 200
                      zKeyBuffer = "File1.dat"
                      keynumber = -64
                      result = BTRIEVE(op, PositionBlock, c, datalength, zKeyBuffer, keylength, keynumber)
                      If result = 0 Then
                        op = 12 'get first
                        datalength = 203
                        keynumber = 2
                        result = BTRIEVE(op, PositionBlock, c, datalength, zKeyBuffer, keylength, keynumber)
                        If result = 0 Then
                          'With Grid1
                          '  .Cell(1, 2).Text = c.FirstName
                          '  .Cell(2, 2).Text = c.LastName
                          '  .Cell(3, 2).Text = c.Address1
                          '  .Cell(4, 2).Text = c.Address2
                          '  .Cell(5, 2).Text = c.City
                          '  .Cell(6, 2).Text = c.STATE
                          '  .Cell(7, 2).Text = c.ZIP
                          '  .Cell(8, 2).Text = c.HomePhone
                          '  .Cell(9, 2).Text = c.WorkPhone
                          '  .Cell(14, 2).Text = CVI(c.number)
                          '  .Cell(15, 2).Text = c.ID
                          '  .Cell(16, 2).Text = CVL(c.BAL)
                          'End With
                        End If
                      Else
                        MsgBox "unable to open " + zKeyBuffer
                      End If
                    Case 1, 2, 3
                      If Index = 1 Then op = 6  'get next
                      If Index = 2 Then op = 7  'get previous
                      If Index = 3 Then op = 13 'get last
                       datalength = 203
                      keynumber = 2
                      result = BTRIEVE(op, PositionBlock, c, datalength, zKeyBuffer, keylength, keynumber)
                      If result = 0 Then
                        'With Grid1
                        '  .Cell(1, 2).Text = c.FirstName
                        '  .Cell(2, 2).Text = c.LastName
                        '  .Cell(3, 2).Text = c.Address1
                        '  .Cell(4, 2).Text = c.Address2
                        '  .Cell(5, 2).Text = c.City
                        '  .Cell(6, 2).Text = c.STATE
                        '  .Cell(7, 2).Text = c.ZIP
                        '  .Cell(8, 2).Text = c.HomePhone
                        '  .Cell(9, 2).Text = c.WorkPhone
                        '  .Cell(14, 2).Text = CVI(c.number)
                        '  .Cell(15, 2).Text = c.ID
                        '  .Cell(16, 2).Text = CVL(c.BAL)
                        'End With
                      Else
                        If result = 9 Then 'end of file
                          Beep
                        Else
                          MsgBox "error" + Str$(result), , "Get error"
                        End If
                      End If
                    Case Else
                       Beep
                  End Select
                  
                End Sub
                How long is an idea? Write it down.

                Comment


                • #9
                  If anyone wants file1.dat and its key description http://www.dotysoftware.com/roy.zip
                  How long is an idea? Write it down.

                  Comment


                  • #10
                    Originally posted by Roy Bauer View Post
                    Thanks for your response. You are correct that vb 6 allows the use of "ANY" in the Declare, but VB.Net doesn't allow it.. Something to do with managed versus unmanaged memory.
                    You could compensate VB6's "As Any" with VB.NET's overloading. "As Any" is the cheap overloading for languages which do not provide overloading.

                    Comment


                    • #11
                      Thanks for all the responses and Code Examples. I have done some BTRIEVE and VB6 and it is pretty straight forward relative to familiarity with PowerBasic. VB.NET is a different animal because it seems that data structures are different. ASCIIZ and ANY aren't available. It kind of like, you know English well and all the slang words, and you know a bit of Spanish but cant understand the Spanish slang language at all.

                      Roy

                      Comment


                      • #12
                        More on this topic. Pervasive has an example of using Btrieve with .Net. The example defines data structures as sequential (verses explicit). So all the data in the example is written in byte format and read in byte (Character) format and run through a converter (Marshalling) to and from the BTRCALL, It works, but all my data files are defined in UDF's (Data Type) with both strings and numeric variables.

                        There are a couple of companies out there that have written "CLASSES" for interfacing with Pervasive SQL, but they are pretty pricey.

                        Comment

                        Working...
                        X