Skip to main content
The CallbackFunction class wraps a CLR (C#) function so it can be called from Lua scripts.

Constructor

CallbackFunction
constructor
Creates a new CallbackFunction.
var callback = new CallbackFunction(
    (ctx, args) => LuaValue.NewString("Hello!"),
    "greet"
);

Properties

Name
string
Gets the name of the function.
Console.WriteLine(callback.Name); // "greet"
ClrCallback
Func<ScriptExecutionContext, CallbackArguments, LuaValue>
Gets the underlying CLR callback delegate.
DefaultAccessMode
InteropAccessMode
Gets or sets the default access mode used when marshalling delegates. Default, HideMembers, and BackgroundOptimized are NOT supported.
CallbackFunction.DefaultAccessMode = InteropAccessMode.Reflection;

Methods

Invoke
method
Invokes the callback function.
returns
LuaValue
The result of the callback
LuaValue result = callback.Invoke(ctx, args, false);

Static Factory Methods

FromDelegate
method
Creates a CallbackFunction from a delegate.
returns
CallbackFunction
A CallbackFunction wrapping the delegate
Func<int, int, int> add = (a, b) => a + b;
CallbackFunction callback = CallbackFunction.FromDelegate(script, add);
script.Globals["add"] = callback;
FromMethodInfo
method
Creates a CallbackFunction from a MethodInfo.
returns
CallbackFunction
A CallbackFunction wrapping the method
var method = typeof(Console).GetMethod("WriteLine", new[] { typeof(string) });
var callback = CallbackFunction.FromMethodInfo(script, method);
script.Globals["print"] = callback;
CheckCallbackSignature
method
Checks if a method signature is compatible for direct callbacks.
returns
bool
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.

Build docs developers (and LLMs) love