Visual Basic .NET

 

Adding uCalc to your VB.NET application

 

In order to implement uCalc FMP in Visual Basic .NET, copy uCalcNET.vb to your project directory (or an appropriate include directory).  Then place the uCalc DLL files either in the Windows System directory, your project's Bin directory, or any suitable directory that is in the path.  From the menu, go to Project / Add Existing Item..., and select uCalcNET.vb.  Now, the parser is fully ready to perform.

 

 

Demo program

 

The name of the uCalc demo solution file to load up in VB.NET is DemoNET.sln.  The source code in the project demonstrates the essential features, especially as they relate to VB.NET.  DemoNET.vb contains the callback functions, and FormNET.vb contains the main part of the code that relates to uCalc.

 

 

Variable attachments under managed code

 

Because managed code may move variable addresses at any time, it is not possible attach a uCalc variable to the address of a variable in your VB.NET code.  Even if you pin the address, the pinning effect is temporary.  Therefore, you should use ucSetValueDbl whenever you want to update the value of a uCalc variable (of Double type) that is associated with a VB.NET variable.  For instance here is a piece of VB Classic code, followed by its VB.NET equivalent:

 

VB Classic code

 

xPtr = ucDefineVariable("x As Double", VarPtr(x))

ExprPtr = ucParse("x^2 + 5")  

  

For x = 1 To 1000000

   SumTotal = SumTotal + ucEvaluate(ExprPtr)

Next

 

 

VB.NET equivalent

 

xPtr = ucDefineVariable("x As Double")

ExprPtr = ucParse("x^2 + 5")

 

For x = 1 To 1000000

   ucSetValueDbl(xPtr, x)

   SumTotal = SumTotal + ucEvaluate(ExprPtr)

Next

 

 

Callbacks under managed code

 

uCalc callbacks under VB.NET's managed code is handled quite differently than from under VB classic and the other compilers supported by uCalc.  With the other compilers, you can use various non-generic data types, and you can choose to pass arguments by value or by reference.  Secondly, you can directly pass a function's address to uCalc with other compilers.  In VB.NET, you must use delegates for callbacks, and you can only use the Double or Long type for numeric, and a generic String type for strings.  Be sure to remember to always specify data types for the function's arguments as well as its return value.

 

In VB.NET, your callback must be a Sub, instead of Function.  And unlike with other compilers, this Sub takes exactly one Integer argument (regardless of the number and type of arguments that are in the definition), which is to be used with ucParam and ucReturn.  Your callback retrieves arguments using ucParamDbl, ucParamLng, or ucParamStr.  Values are returned using ucReturnDbl (for numeric), or ucReturnStr (for string).

 

Also, expressions that are passed ByExpr should be retrieved using ucParamExpr().  For instance, in VB classic, where you would have ucEvaluate(Arg1ExprHandle), in VB.NET it would be ucEvaluate(ucParamExpr(Expr, 1)).  See MyIIF below.

 

Here are examples taken from the demo program:

 

Static d_MyCallback As ucCallback = New ucCallback(AddressOf MyEasyCallback)

Static d_MyMsgBox As ucCallback = New ucCallback(AddressOf MyMsgBox)

Static d_MyLeft As ucCallback = New ucCallback(AddressOf MyLeft)

Static d_MyIIf As ucCallback = New ucCallback(AddressOf MyIIf)

 

ucDefineFunction("MyCallback(a As Double, b As Double, c As Double) As Double", d_MyCallback)

ucDefineFunction("MyMsgBox(Prompt As String, Buttons As Long = 0, Title As String = 'uCalc') As Double", d_MyMsgBox)

ucDefineFunction("MyLeft(Text As String, Count As Long) As String", d_MyLeft)

ucDefineFunction("MyIIf(cond As Long, ByExpr TruePart, ByExpr FalsePart) As Double", d_MyIIf)

 

Module DemoVB   

    Sub MyCallback(ByVal Expr As Integer)

        ucReturnDbl(Expr, ucParamDbl(Expr, 1) + ucParamDbl(Expr, 2) + ucParamDbl(Expr, 3))

    End Sub

 

    Sub MyMsgBox(ByVal Expr As Integer)

        ucReturnDbl(Expr, MsgBox(ucParamStr(Expr, 1), ucParamLng(Expr, 2), ucParamStr(Expr, 3)))

    End Sub   

 

    Sub MyLeft(ByVal Expr As Integer)

        ucReturnStr(Expr, Left$(ucParamStr(Expr, 1), ucParamLng(Expr, 2)))

    End Sub

 

    Sub MyIIF(ByVal Expr As Integer)

        If ucParamLng(Expr, 1) Then

            ucReturnDbl(Expr, ucEvaluate(ucParamExpr(Expr, 2)))

        Else

            ucReturnDbl(Expr, ucEvaluate(ucParamExpr(Expr, 3)))

        End If

    End Sub

End Module