uCalc API Version: 2.1.3-preview.2 Released: 6/16/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.
SetScalar
Method
Product:
Class:
Performs a low-level copy of a scalar value from a source memory address to a destination address.
Syntax
Parameters
Return
void
This method does not return a value.
Remarks
💾 Direct Memory Copy: SetScalar
The SetScalar method performs a low-level, direct memory copy of a scalar value from a source address to a destination address. It is the uCalc equivalent of C's memcpy for single scalar values.
🎯 Primary Use Case: Callbacks
The most common use for SetScalar is within callback routines for custom functions and operators, particularly when arguments are passed by reference (ByRef). In these scenarios, you receive a pointer to the original variable's data, and SetScalar provides the mechanism to modify that data.
🤔 How is this different from regular assignment?
In a uCalc script, you would simply write MyVar1 = MyVar2;. However, inside a host application callback (C#, C++, VB), you are working with pointers to uCalc's internal memory. The standard assignment operator (=) of the host language cannot modify uCalc's memory directly. SetScalar bridges this gap, allowing your host code to manipulate the script's variables.
⚠️ Important Considerations
- Type Safety:
SetScalarperforms a raw byte-for-byte copy. It does not perform any type checking or conversion. Copying between pointers of different data types can lead to undefined behavior or corrupted data if their sizes differ. - Strings and Complex Types: While
SetScalarworks for strings, it's managing uCalc's internal string representation. The copy is handled correctly, including reference counting. For other complex types, ensure you are copying between identical types.
Examples
SetScalar
using uCalcSoftware;
var uc = new uCalc();
var MyVar1 = uc.DefineVariable("MyVar1 = 123.456");
var MyVar2 = uc.DefineVariable("MyVar2 = 654.321");
var MyStr1 = uc.DefineVariable("MyStr1 = 'First string'");
var MyStr2 = uc.DefineVariable("MyStr2 = 'Second string'");
uc.DataTypeOf("double").SetScalar(MyVar1.ValueAddr(), MyVar2.ValueAddr());
uc.DataTypeOf("string").SetScalar(MyStr1.ValueAddr(), MyStr2.ValueAddr());
Console.WriteLine(uc.EvalStr("MyVar1")); // Now contains value copied from MyVar2
Console.WriteLine(uc.EvalStr("MyStr1")); // Now contains value copied from MyStr2
654.321
Second string using uCalcSoftware; var uc = new uCalc(); var MyVar1 = uc.DefineVariable("MyVar1 = 123.456"); var MyVar2 = uc.DefineVariable("MyVar2 = 654.321"); var MyStr1 = uc.DefineVariable("MyStr1 = 'First string'"); var MyStr2 = uc.DefineVariable("MyStr2 = 'Second string'"); uc.DataTypeOf("double").SetScalar(MyVar1.ValueAddr(), MyVar2.ValueAddr()); uc.DataTypeOf("string").SetScalar(MyStr1.ValueAddr(), MyStr2.ValueAddr()); Console.WriteLine(uc.EvalStr("MyVar1")); // Now contains value copied from MyVar2 Console.WriteLine(uc.EvalStr("MyStr1")); // Now contains value copied from MyStr2
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto MyVar1 = uc.DefineVariable("MyVar1 = 123.456");
auto MyVar2 = uc.DefineVariable("MyVar2 = 654.321");
auto MyStr1 = uc.DefineVariable("MyStr1 = 'First string'");
auto MyStr2 = uc.DefineVariable("MyStr2 = 'Second string'");
uc.DataTypeOf("double").SetScalar(MyVar1.ValueAddr(), MyVar2.ValueAddr());
uc.DataTypeOf("string").SetScalar(MyStr1.ValueAddr(), MyStr2.ValueAddr());
cout << uc.EvalStr("MyVar1") << endl; // Now contains value copied from MyVar2
cout << uc.EvalStr("MyStr1") << endl; // Now contains value copied from MyStr2
}
654.321
Second string #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto MyVar1 = uc.DefineVariable("MyVar1 = 123.456"); auto MyVar2 = uc.DefineVariable("MyVar2 = 654.321"); auto MyStr1 = uc.DefineVariable("MyStr1 = 'First string'"); auto MyStr2 = uc.DefineVariable("MyStr2 = 'Second string'"); uc.DataTypeOf("double").SetScalar(MyVar1.ValueAddr(), MyVar2.ValueAddr()); uc.DataTypeOf("string").SetScalar(MyStr1.ValueAddr(), MyStr2.ValueAddr()); cout << uc.EvalStr("MyVar1") << endl; // Now contains value copied from MyVar2 cout << uc.EvalStr("MyStr1") << endl; // Now contains value copied from MyStr2 }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim MyVar1 = uc.DefineVariable("MyVar1 = 123.456")
Dim MyVar2 = uc.DefineVariable("MyVar2 = 654.321")
Dim MyStr1 = uc.DefineVariable("MyStr1 = 'First string'")
Dim MyStr2 = uc.DefineVariable("MyStr2 = 'Second string'")
uc.DataTypeOf("double").SetScalar(MyVar1.ValueAddr(), MyVar2.ValueAddr())
uc.DataTypeOf("string").SetScalar(MyStr1.ValueAddr(), MyStr2.ValueAddr())
Console.WriteLine(uc.EvalStr("MyVar1")) '// Now contains value copied from MyVar2
Console.WriteLine(uc.EvalStr("MyStr1")) '// Now contains value copied from MyStr2
End Sub
End Module
654.321
Second string Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim MyVar1 = uc.DefineVariable("MyVar1 = 123.456") Dim MyVar2 = uc.DefineVariable("MyVar2 = 654.321") Dim MyStr1 = uc.DefineVariable("MyStr1 = 'First string'") Dim MyStr2 = uc.DefineVariable("MyStr2 = 'Second string'") uc.DataTypeOf("double").SetScalar(MyVar1.ValueAddr(), MyVar2.ValueAddr()) uc.DataTypeOf("string").SetScalar(MyStr1.ValueAddr(), MyStr2.ValueAddr()) Console.WriteLine(uc.EvalStr("MyVar1")) '// Now contains value copied from MyVar2 Console.WriteLine(uc.EvalStr("MyStr1")) '// Now contains value copied from MyStr2 End Sub End Module
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 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)"));
#include
#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 #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; }
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 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