The CallbackFunction class wraps a CLR (C#) function so it can be called from Lua scripts.
Constructor
Creates a new CallbackFunction.
callBack
Func<ScriptExecutionContext, CallbackArguments, LuaValue>
required
The callback function to be called
The callback name, used in stack traces and debugger (optional)
var callback = new CallbackFunction(
(ctx, args) => LuaValue.NewString("Hello!"),
"greet"
);
Properties
Gets the name of the function.Console.WriteLine(callback.Name); // "greet"
ClrCallback
Func<ScriptExecutionContext, CallbackArguments, LuaValue>
Gets the underlying CLR callback delegate.
Gets or sets the default access mode used when marshalling delegates. Default, HideMembers, and BackgroundOptimized are NOT supported.CallbackFunction.DefaultAccessMode = InteropAccessMode.Reflection;
Methods
Invokes the callback function.
executionContext
ScriptExecutionContext
required
The execution context
Whether this is a method call (affects ‘self’ handling) (optional, default false)
The result of the callback
LuaValue result = callback.Invoke(ctx, args, false);
Static Factory Methods
Creates a CallbackFunction from a delegate.
The access mode (optional, defaults to DefaultAccessMode)
A CallbackFunction wrapping the delegate
Func<int, int, int> add = (a, b) => a + b;
CallbackFunction callback = CallbackFunction.FromDelegate(script, add);
script.Globals["add"] = callback;
Creates a CallbackFunction from a MethodInfo.
The object for instance methods, or null for static methods (optional)
The access mode (optional)
A CallbackFunction wrapping the method
var method = typeof(Console).GetMethod("WriteLine", new[] { typeof(string) });
var callback = CallbackFunction.FromMethodInfo(script, method);
script.Globals["print"] = callback;
Checks if a method signature is compatible for direct callbacks.
Whether to require public visibility
True if the signature is compatible
A compatible signature must:
- Take two parameters:
ScriptExecutionContext and CallbackArguments
- Return
LuaValue
- Be public (if requirePublicVisibility is true)
public LuaValue MyCallback(ScriptExecutionContext ctx, CallbackArguments args)
{
return LuaValue.NewString("Valid signature!");
}
var method = typeof(MyClass).GetMethod("MyCallback");
bool isValid = CallbackFunction.CheckCallbackSignature(method, true);
Example Usage
using SolarSharp.Interpreter;
using SolarSharp.Interpreter.DataTypes;
using SolarSharp.Interpreter.Execution;
var script = new Script();
// Simple callback with lambda
script.Globals["hello"] = new CallbackFunction(
(ctx, args) => {
return LuaValue.NewString("Hello, World!");
},
"hello"
);
script.DoString("print(hello())"); // Hello, World!
// Callback with arguments
script.Globals["add"] = new CallbackFunction(
(ctx, args) => {
double a = args[0].Number;
double b = args[1].Number;
return LuaValue.NewNumber(a + b);
},
"add"
);
var result = script.DoString("return add(10, 20)");
Console.WriteLine(result.Number); // 30
// Using FromDelegate
Func<string, string> toUpper = s => s.ToUpper();
script.Globals["toUpper"] = CallbackFunction.FromDelegate(script, toUpper);
script.DoString(@"
local upper = toUpper('hello')
print(upper) -- HELLO
");
// Callback with error handling
script.Globals["divide"] = new CallbackFunction(
(ctx, args) => {
double a = args[0].Number;
double b = args[1].Number;
if (b == 0)
throw new ScriptRuntimeException("Division by zero");
return LuaValue.NewNumber(a / b);
},
"divide"
);
// Using CallbackArguments helpers
script.Globals["processUser"] = new CallbackFunction(
(ctx, args) => {
// Type checking with AsType
string name = args.AsType(0, "processUser", DataType.String).String;
int age = args.AsInt(1, "processUser");
bool active = args.AsOptBoolean(2, "processUser") ?? true;
Console.WriteLine($"User: {name}, Age: {age}, Active: {active}");
return LuaValue.Nil;
},
"processUser"
);
script.DoString("processUser('Alice', 30, false)");
// Accessing the script from callback
script.Globals["getGlobal"] = new CallbackFunction(
(ctx, args) => {
string key = args[0].String;
return ctx.GetScript().Globals.Get(key);
},
"getGlobal"
);
script.Globals["myValue"] = 42;
var value = script.DoString("return getGlobal('myValue')");
Console.WriteLine(value.Number); // 42
Callback Signature Requirements
For a method to be directly usable as a callback (without wrapping), it must match this signature:
public LuaValue MethodName(ScriptExecutionContext context, CallbackArguments args)
{
// Implementation
return LuaValue.NewNumber(42);
}
If your method doesn’t match this signature, use FromDelegate or FromMethodInfo which will automatically create an adapter.