Main Page | Features | Central Services | csv-Files | Types | Transfer | Access | API-C | API-VB/ActiveX | API-Java | Examples | Downloads
Using Tagged Structures in Visual Basic 6

Tagged structures in Visual Basic are in close analogy with their counterparts in C. The principal caveates include

An in C, the first step is to register the structure. You do this at initialization time by declaring a structure tag name and filling in the sizes and locations of the individual elements. Then when a client sends or asks for a structure and it sends the structure tag along with the request, the server knows all about the structure and how to handle it.

In Visual Basic this might look like

' make sure tine.bas is included in the project !
Option Explicit
Private Const NUM_DEVICES = 10
Private Const NUM_VALUES = 1024 * 8

Private Type SineInfo
  amplitude As Single
  frequency As Single
  noise As Single
  phase As Single
  numberCalls As Long
  Description(63) As Byte
End Type

Dim sineInfoTable(NUM_DEVICES - 1) As SineInfo
'other variables omitted ...

Private Sub Form_Load()
  ' other initialization omitted ....
  Call RegisterStructs
  ' other initialization omitted ....
End Sub

Sub RegisterStructs()
  Dim offset As Long
  ' this must follow the order of the structure explicitly!
  ' note: in VB the alignment is always 4-bytes (do not leave alignment gaps!)
  '       offset is then always the accumulated size in bytes (Len) of the structure fields
  AddFieldToStruct "SineInfo", offset, 1, CF_FLOAT, "amplitude"
  offset = offset + Len(sineInfoTable(0).amplitude)
  AddFieldToStruct "SineInfo", offset, 1, CF_FLOAT, "frequency"
  offset = offset + Len(sineInfoTable(0).frequency)
  AddFieldToStruct "SineInfo", offset, 1, CF_FLOAT, "noise"
  offset = offset + Len(sineInfoTable(0).noise)
  AddFieldToStruct "SineInfo", offset, 1, CF_FLOAT, "phase"
  offset = offset + Len(sineInfoTable(0).phase)
  AddFieldToStruct "SineInfo", offset, 1, CF_LONG, "numberCalls"
  offset = offset + Len(sineInfoTable(0).numberCalls)
  AddFieldToStruct "SineInfo", offset, 64, CF_TEXT, "Description"
  ' terminate the registration :
  SealTaggedStruct "SineInfo", Len(sineInfoTable(0)), NUM_DEVICES

End Sub


A Visual Basic server then might make use of something like the following within its equiment module dispatch event handler:

Private Sub Srv1_EqpFcn(ByVal DevName As String, ByVal devProperty As String, ByVal outArrayLen As Long, ByVal inArrayLen As Long, ByVal devAccess As Integer)
  Dim devnr As Integer, i As Integer, cc As Integer
  Dim sinf As SineInfo

  devnr = Srv1.EqpGetModuleNumber(DevName)
  If (devnr < 0 Or devnr >= NUM_DEVICES) Then
    Srv1.EqpSetCompletion illegal_equipment_number, ""
    Exit Sub
  End If

  Select Case devProperty
    Case "Sine":
        If (devAccess And CA_WRITE) = CA_WRITE Then
          Srv1.EqpSetCompletion illegal_read_write, ""
          Exit Sub
        End If
        Srv1.EqpSendData sinbuf(0, devnr)
        sineInfoTable(devnr).numberCalls = sineInfoTable(devnr).numberCalls + 1
   ' other properties omitted ...
    Case "SineInfo":
        If (inArrayLen > 0) Then
          If (devAccess And CA_WRITE) <> CA_WRITE Then
            Srv1.EqpSetCompletion illegal_read_write, ""
            Exit Sub
          End If
        ' allow an atomic set of all relevant values this way ...
          cc = 0
          Srv1.EqpRecvData sinf.amplitude
          If (sinf.amplitude < 1 Or sinf.amplitude > 1000) Then cc = out_of_range
          If (sinf.frequency < 1 Or sinf.frequency > 100) Then cc = out_of_range
          If (sinf.phase < 1 Or sinf.phase > 512) Then cc = out_of_range
          If (sinf.noise < 1 Or sinf.noise > 100) Then cc = out_of_range
          If cc <> 0 Then
            Srv1.EqpSetCompletion cc, ""
            Exit Sub
          End If
          sineInfoTable(devnr) = sinf
        End If
        If (outArrayLen > 0) Then
          Srv1.EqpSendData sineInfoTable(0).amplitude
        End If
    Case Else:
        Srv1.EqpSetCompletion illegal_property, ""
        Exit Sub
  End Select
  
  Srv1.EqpSetCompletion 0, ""

End Sub

A Visual Basic client application would access a user-defined structure using code something like the following:

' Example using an ACOP control to get an array of structures ...
Dim sininf(9) As SineInfo

sub GetSineInfo()
  Dim rc As Integer

  ACOP1.DeviceContext = "TEST"
  ACOP1.DeviceGroup = "SineServer"
  ACOP1.DeviceName = "SineGen0"
  ACOP1.AccessRate = 1000 '
  ACOP1.AccessMode = "READ"
  ACOP1.DeviceProperty = "SineInfo"

  rc = ACOP1.Execute(sininf(0).amplitude, 10, "STRUCT/SineInfo")

End Sub

Generated for TINE API by  doxygen 1.5.8