uCalc API Version: 2.1.3-preview.2 Released: 6/17/2026

Warning

uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.

ValueAddr()

Method

Product: 

Fast Math Parser

Class: 

Item

Returns the memory address of an item's value, enabling low-level interoperability and direct memory manipulation.

Syntax

ValueAddr()

Parameters

[None]

Return

IntPtr

A pointer to the item's underlying value. The exact type is platform-dependent (e.g., IntPtr in .NET).

Remarks

The ValueAddr method provides a way to get a direct pointer to the memory location where a uCalc item's value is stored. This is an advanced feature primarily used for high-performance scenarios, such as binding uCalc variables to variables in the host application or modifying values by reference within a callback.

Core Use Cases

  • Host Application Binding: Link a uCalc variable directly to a native variable in C++, C#, or VB.
  • Passing by Reference: Obtain a pointer to pass to a callback function that needs to modify the original value.
  • Low-Level Introspection: Use with methods like ValueAt to dereference the pointer and read the value.

ValueAddr vs. ValuePtr: The Critical Distinction

It is essential to understand the difference between ValueAddr() and ValuePtr(), especially when working with pointer-type variables. Failing to do so can lead to subtle bugs or memory access errors.

MethodDescriptionExample Scenario
ValueAddr()Returns the memory address OF the item itself.If you have a variable x, x.ValueAddr() gives you the location where the value of x is stored.
ValuePtr()Returns the memory address STORED IN the item.If you have a variable p As Int Ptr, p.ValuePtr() gives you the address that p is pointing to, not the address of p itself.

In short: ValueAddr is for getting the address of any variable, while ValuePtr is for getting the address held by a pointer variable.


⚖️ Comparative Analysis

  • vs. C++ (& operator): ValueAddr() is conceptually similar to C++'s address-of operator (&). int x = 10; int* p = &x; is analogous to var x = uc.DefineVariable("x=10"); var p = x.ValueAddr();.

  • vs. C# (unsafe context): In C#, getting the address of a managed variable requires an unsafe block and fixed pointers. uCalc provides a safer, managed way to achieve similar low-level memory access without leaving the managed environment, abstracting away the complexities of garbage collection and memory pinning.

Examples

Pointer value with ValueAt
				
					using uCalcSoftware;

var uc = new uCalc();
uc.Format("Result = 'Answer: <' + Result + '>'");

var Dbl = uc.DefineVariable("MyDouble = 123.456");

Console.WriteLine(uc.ValueAt(Dbl.ValueAddr(), "Double"));
Console.WriteLine(uc.ValueAt(Dbl.ValueAddr(), BuiltInType.Float_Double));
Console.WriteLine(uc.ValueAt(Dbl.ValueAddr(), BuiltInType.Float_Double, true));


				
			
123.456
123.456
Answer: <123.456>
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uc.Format("Result = 'Answer: <' + Result + '>'");

   auto Dbl = uc.DefineVariable("MyDouble = 123.456");

   cout << uc.ValueAt(Dbl.ValueAddr(), "Double") << endl;
   cout << uc.ValueAt(Dbl.ValueAddr(), BuiltInType::Float_Double) << endl;
   cout << uc.ValueAt(Dbl.ValueAddr(), BuiltInType::Float_Double, true) << endl;


}
				
			
123.456
123.456
Answer: <123.456>
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      uc.Format("Result = 'Answer: <' + Result + '>'")
      
      Dim Dbl = uc.DefineVariable("MyDouble = 123.456")
      
      Console.WriteLine(uc.ValueAt(Dbl.ValueAddr(), "Double"))
      Console.WriteLine(uc.ValueAt(Dbl.ValueAddr(), BuiltInType.Float_Double))
      Console.WriteLine(uc.ValueAt(Dbl.ValueAddr(), BuiltInType.Float_Double, true))
      
      
   End Sub
End Module
				
			
123.456
123.456
Answer: <123.456>
Returning a pointer with ReturnPtr
				
					using uCalcSoftware;

var uc = new uCalc();

static void GetAddressOf(uCalc.Callback cb) {
   cb.ReturnPtr(cb.ArgItem(1).ValueAddr());
}


// This example is for sake of illustration
// There is already a built-in AddressOf() function

uc.DefineFunction("GetAddressOf(ByHandle Variable As AnyType) As SameTypeAs:0 Ptr", GetAddressOf);

uc.DefineVariable("MyVariable = 123.456");
uc.DefineVariable("MyStr = 'Hello world!'");

Console.WriteLine(uc.EvalStr("ValueAt(GetAddressOf(MyVariable))"));
Console.WriteLine(uc.EvalStr("ValueAt(GetAddressOf(MyStr))"));
				
			
123.456
Hello world!
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

void ucalc_call GetAddressOf(uCalcBase::Callback cb) {
   cb.ReturnPtr(cb.ArgItem(1).ValueAddr());
}
int main() {
   uCalc uc;

   // This example is for sake of illustration
   // There is already a built-in AddressOf() function

   uc.DefineFunction("GetAddressOf(ByHandle Variable As AnyType) As SameTypeAs:0 Ptr", GetAddressOf);

   uc.DefineVariable("MyVariable = 123.456");
   uc.DefineVariable("MyStr = 'Hello world!'");

   cout << uc.EvalStr("ValueAt(GetAddressOf(MyVariable))") << endl;
   cout << uc.EvalStr("ValueAt(GetAddressOf(MyStr))") << endl;
}
				
			
123.456
Hello world!
				
					Imports System
Imports uCalcSoftware
Public Module Program
   
   Public Sub GetAddressOf(ByVal cb As uCalc.Callback)
      cb.ReturnPtr(cb.ArgItem(1).ValueAddr())
   End Sub
   Public Sub Main()
      Dim uc As New uCalc()
      
      '// This example is for sake of illustration
      '// There is already a built-in AddressOf() function
      
      uc.DefineFunction("GetAddressOf(ByHandle Variable As AnyType) As SameTypeAs:0 Ptr", AddressOf GetAddressOf)
      
      uc.DefineVariable("MyVariable = 123.456")
      uc.DefineVariable("MyStr = 'Hello world!'")
      
      Console.WriteLine(uc.EvalStr("ValueAt(GetAddressOf(MyVariable))"))
      Console.WriteLine(uc.EvalStr("ValueAt(GetAddressOf(MyStr))"))
   End Sub
End Module
				
			
123.456
Hello world!
DefineVariable; using pointers
				
					using uCalcSoftware;

var uc = new uCalc();
var Int8Var = uc.DefineVariable("x As Int8 = -1");
var Int16Var = uc.DefineVariable("y As Int16 = -1");
var StrVar = uc.DefineVariable("MyStr = 'Hello there'");
Console.WriteLine(uc.EvalStr("x"));
Console.WriteLine(uc.EvalStr("y"));
Console.WriteLine(uc.EvalStr("MyStr"));

var xPtr = uc.DefineVariable("xPtr As Pointer"); // General pointer
var yPtr = uc.DefineVariable("yPtr As Int16u Ptr"); // pointer specific to unsigned Int16
var yPtrB = uc.DefineVariable("yPtrB As Int16 Ptr = AddressOf(y)"); // Using AddressOf
var StrPtr = uc.DefineVariable("StrPtr As String Ptr");
xPtr.ValuePtr(Int8Var.ValueAddr()); // Sets the pointer address
yPtr.ValuePtr(Int16Var.ValueAddr()); // Note: address of signed Int16 going to an unsigned Ptr
StrPtr.ValuePtr(StrVar.ValueAddr());

// Note: for the ints we are now returning unsigned values; so -1 turns into positive numbers
Console.WriteLine(uc.EvalStr("ValueAt(Int8u, xPtr)")); // Type required because it's defined as generar pointer
Console.WriteLine(uc.EvalStr("ValueAt(yPtr)")); // Type name not needed because it's defined as Int16u Ptr
Console.WriteLine(uc.EvalStr("ValueAt(yPtrB)"));
Console.WriteLine(uc.EvalStr("ValueAt(StrPtr)"));

// Iterate through uc.ItemOf(ItemIs.DataType, n).Name()
// to see data type names you can use with ValueAt

var OtherInt = uc.DefineVariable("OtherInt As Int16 = 1234");
uc.DataTypeOf(BuiltInType.Integer_16).SetScalar(Int16Var.ValueAddr(), OtherInt.ValueAddr());

Console.WriteLine(uc.EvalStr("OtherInt"));
Console.WriteLine(uc.EvalStr("ValueAt(yPtrB)"));





				
			
-1
-1
Hello there
255
65535
-1
Hello there
1234
1234
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   auto Int8Var = uc.DefineVariable("x As Int8 = -1");
   auto Int16Var = uc.DefineVariable("y As Int16 = -1");
   auto StrVar = uc.DefineVariable("MyStr = 'Hello there'");
   cout << uc.EvalStr("x") << endl;
   cout << uc.EvalStr("y") << endl;
   cout << uc.EvalStr("MyStr") << endl;

   auto xPtr = uc.DefineVariable("xPtr As Pointer"); // General pointer
   auto yPtr = uc.DefineVariable("yPtr As Int16u Ptr"); // pointer specific to unsigned Int16
   auto yPtrB = uc.DefineVariable("yPtrB As Int16 Ptr = AddressOf(y)"); // Using AddressOf
   auto StrPtr = uc.DefineVariable("StrPtr As String Ptr");
   xPtr.ValuePtr(Int8Var.ValueAddr()); // Sets the pointer address
   yPtr.ValuePtr(Int16Var.ValueAddr()); // Note: address of signed Int16 going to an unsigned Ptr
   StrPtr.ValuePtr(StrVar.ValueAddr());

   // Note: for the ints we are now returning unsigned values; so -1 turns into positive numbers
   cout << uc.EvalStr("ValueAt(Int8u, xPtr)") << endl; // Type required because it's defined as generar pointer
   cout << uc.EvalStr("ValueAt(yPtr)") << endl; // Type name not needed because it's defined as Int16u Ptr
   cout << uc.EvalStr("ValueAt(yPtrB)") << endl;
   cout << uc.EvalStr("ValueAt(StrPtr)") << endl;

   // Iterate through uc.ItemOf(ItemIs.DataType, n).Name()
   // to see data type names you can use with ValueAt

   auto OtherInt = uc.DefineVariable("OtherInt As Int16 = 1234");
   uc.DataTypeOf(BuiltInType::Integer_16).SetScalar(Int16Var.ValueAddr(), OtherInt.ValueAddr());

   cout << uc.EvalStr("OtherInt") << endl;
   cout << uc.EvalStr("ValueAt(yPtrB)") << endl;





}
				
			
-1
-1
Hello there
255
65535
-1
Hello there
1234
1234
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim Int8Var = uc.DefineVariable("x As Int8 = -1")
      Dim Int16Var = uc.DefineVariable("y As Int16 = -1")
      Dim StrVar = uc.DefineVariable("MyStr = 'Hello there'")
      Console.WriteLine(uc.EvalStr("x"))
      Console.WriteLine(uc.EvalStr("y"))
      Console.WriteLine(uc.EvalStr("MyStr"))
      
      Dim xPtr = uc.DefineVariable("xPtr As Pointer") '// General pointer
      Dim yPtr = uc.DefineVariable("yPtr As Int16u Ptr") '// pointer specific to unsigned Int16
      Dim yPtrB = uc.DefineVariable("yPtrB As Int16 Ptr = AddressOf(y)") '// Using AddressOf
      Dim StrPtr = uc.DefineVariable("StrPtr As String Ptr")
      xPtr.ValuePtr(Int8Var.ValueAddr()) '// Sets the pointer address
      yPtr.ValuePtr(Int16Var.ValueAddr()) '// Note: address of signed Int16 going to an unsigned Ptr
      StrPtr.ValuePtr(StrVar.ValueAddr())
      
      '// Note: for the ints we are now returning unsigned values; so -1 turns into positive numbers
      Console.WriteLine(uc.EvalStr("ValueAt(Int8u, xPtr)")) '// Type required because it's defined as generar pointer
      Console.WriteLine(uc.EvalStr("ValueAt(yPtr)")) '// Type name not needed because it's defined as Int16u Ptr
      Console.WriteLine(uc.EvalStr("ValueAt(yPtrB)"))
      Console.WriteLine(uc.EvalStr("ValueAt(StrPtr)"))
      
      '// Iterate through uc.ItemOf(ItemIs.DataType, n).Name()
      '// to see data type names you can use with ValueAt
      
      Dim OtherInt = uc.DefineVariable("OtherInt As Int16 = 1234")
      uc.DataTypeOf(BuiltInType.Integer_16).SetScalar(Int16Var.ValueAddr(), OtherInt.ValueAddr())
      
      Console.WriteLine(uc.EvalStr("OtherInt"))
      Console.WriteLine(uc.EvalStr("ValueAt(yPtrB)"))
      
      
      
      
      
   End Sub
End Module
				
			
-1
-1
Hello there
255
65535
-1
Hello there
1234
1234