Export Functions

Guide to export functions from your plugin to be used by other language modules within Plugify.

In the Plugify ecosystem, C# plugins can export functions to make them accessible to other plugins. This guide explains how to define and export functions in C# and provides examples to help you integrate your plugins seamlessly.

Basic Type Mapping

The following table lists how types are exposed to the C# API:

C++ TypeC# TypePlugify AliasRef Support ?
voidvoidvoid
boolBool8bool
charChar8char8
char16_tChar16char16
int8_tsbyteint8
int16_tshortint16
int32_tintint32
int64_tlongint64
uint8_tbyteuint8
uint16_tushortuint16
uint32_tuintuint32
uint64_tulonguint64
uintptr_tnintptr64
uintptr_tnintptr32
floatfloatfloat
doubledoubledouble
void*Delegatefunction
plg::stringstringstring
plg::anyobjectany
plg::vector<bool>Bool8bool
plg::vector<char>Char8char8
plg::vector<char16_t>Char16char16
plg::vector<int8_t>sbyteint8
plg::vector<int16_t>shortint16
plg::vector<int32_t>intint32
plg::vector<int64_t>longint64
plg::vector<uint8_t>byteuint8
plg::vector<uint16_t>ushortuint16
plg::vector<uint32_t>uintuint32
plg::vector<uint64_t>ulonguint64
plg::vector<uintptr_t>nintptr64
plg::vector<uintptr_t>nintptr32
plg::vector<float>floatfloat
plg::vector<double>doubledouble
plg::vector<plg::string>stringstring
plg::vector<plg::any>objectany
plg::vector<plg::vec2>Vector2vec2
plg::vector<plg::vec3>Vector3vec3
plg::vector<plg::vec4>Vector4vec4
plg::vector<plg::mat4x4>Matrix4x4mat4x4
plg::vec2Vector2vec2
plg::vec3Vector3vec3
plg::vec4Vector4vec4
plg::mat4x4Matrix4x4mat4x4

Exporting Functions in C#

Exporting functions in C# is straightforward because C# is a statically-typed language. You need to define the function and specify it in the plugin manifest. Plugify's C# Language Module handles the rest.

Basic Example

Here’s a simple example of exporting a function in a C# plugin:

Function Definition

plugin.cs
namespace ExampleCSharpPlugin
{
    public static class ExportedFunctions
    {
        /// <summary>
        /// Adds two integers.
        /// </summary>
        /// <param name="a">First integer.</param>
        /// <param name="b">Second integer.</param>
        /// <returns>Sum of a and b.</returns>
        public static int AddNumbers_Exported(int a, int b)
        {
            return a + b;
        }
    }
}

Plugin Manifest

To export the function, describe it in the plugin manifest under the exportedMethods section:

plugin_name.pplugin
{
  "name": "ExampleCSharpPlugin",
  "version": "1.0.0",
  "exportedMethods": [
    {
      "name": "AddNumbers",
      "funcName": "ExampleCSharpPlugin.ExportedFunctions.AddNumbers_Exported",
      "paramTypes": [
        {
          "type": "int32",
          "name": "a"
        },
        {
          "type": "int32",
          "name": "b"
        }
      ],
      "retType": {
        "type": "int32"
      }
    }
  ]
}

Parameter and Return Type Conventions

Plugify uses specific conventions for parameter and return types to ensure compatibility across plugins. Below are the guidelines for C#:

1. Primitive Types

  • Parameter: Pass primitive types (e.g., int, float) directly.
  • Return: Return primitive types directly.

2. Strings

  • Parameter: Pass strings as string.
  • Return: Return strings as string.

3. Arrays

  • Parameter: Pass arrays as T[].
  • Return: Return arrays as T[].

4. Objects

  • Parameter: Pass objects as object.
  • Return: Return objects as object.

Advanced Example: Exporting Complex Functions

Here’s an example of exporting a function with complex parameter and return types:

Function Definition

plugin.cs
namespace ExampleCSharpPlugin
{
    public static class ExportedFunctions
    {
        /// <summary>
        /// Processes an array of doubles and returns an array of strings.
        /// </summary>
        /// <param name="data">Array of double values.</param>
        /// <param name="prefix">Prefix to add to each value.</param>
        /// <returns>Array of formatted strings.</returns>
        public static string[] ProcessData_Exported(double[] data, string prefix)
        {
            return data.Select(value => $"{prefix}{value}").ToArray();
        }
    }
}

Plugin Manifest

plugin_name.pplugin
{
  "name": "ExampleCSharpPlugin",
  "version": "1.0.0",
  "exportedMethods": [
    {
      "name": "ProcessData",
      "funcName": "ExampleCSharpPlugin.ExportedFunctions.ProcessData_Exported",
      "paramTypes": [
        {
          "type": "double[]",
          "name": "data"
        },
        {
          "type": "string",
          "name": "prefix"
        }
      ],
      "retType": {
        "type": "string[]"
      }
    }
  ]
}

Handling Callbacks

Plugify allows you to export functions that accept callbacks as parameters. Here’s an example:

Function Definition

plugin.cs
namespace ExampleCSharpPlugin
{
    public delegate string ExampleCallback(int a, string b);

    public static class ExportedFunctions
    {
        /// <summary>
        /// Executes a callback function with the provided parameters.
        /// </summary>
        /// <param name="value">Integer value.</param>
        /// <param name="inputStr">Input string.</param>
        /// <param name="callback">Callback function to execute.</param>
        public static void ExecuteWithCallback_Exported(int value, string inputStr, ExampleCallback callback)
        {
            string result = callback(value, inputStr);
            Console.WriteLine($"Callback result: {result}");
        }
    }
}

Plugin Manifest

plugin_name.pplugin
{
  "name": "ExampleCSharpPlugin",
  "version": "1.0.0",
  "exportedMethods": [
    {
      "name": "ExecuteWithCallback",
      "funcName": "ExampleCSharpPlugin.ExportedFunctions.ExecuteWithCallback_Exported",
      "paramTypes": [
        {
          "type": "int32",
          "name": "value"
        },
        {
          "type": "string",
          "name": "inputStr"
        },
        {
          "type": "function",
          "name": "callback",
          "prototype": {
            "name": "ExampleCallback",
            "funcName": "ExampleCallback_Exported",
            "paramTypes": [
              {
                "type": "int32",
                "name": "value"
              },
              {
                "type": "string",
                "name": "inputStr"
              }
            ],
            "retType": {
              "type": "string"
            }
          }
        }
      ],
      "retType": {
        "type": "void"
      }
    }
  ]
}

Best Practices

  1. Define Functions Clearly: Ensure your functions are well-documented and easy to understand.
  2. Follow Type Conventions: Adhere to Plugify's type conventions for parameters and return values.
  3. Test Thoroughly: Test your exported functions to ensure they work as expected when called by other plugins.
  4. Update the Manifest: Always describe exported functions in the plugin manifest under the exportedMethods section.

Conclusion

Exporting functions in C# plugins is simple and straightforward. By defining your functions and describing them in the plugin manifest, you can create robust and interoperable plugins. For more advanced use cases, such as handling callbacks, use the techniques outlined in this guide.