Export Functions
Guide to export functions from your plugin to be used by other language modules within Plugify.
In the Plugify ecosystem, Go plugins can export functions to make them accessible to other plugins. This guide explains how to define and export functions in Go and provides examples to help you integrate your plugins seamlessly.
Basic Type Mapping
The following table lists how types are exposed to the Go API:
| C++ Type | Go Type | Plugify Alias | Ref Support ? |
|---|---|---|---|
| void | void (not used in Go) | void | ❌ |
| bool | bool | bool | ✅ |
| char | int8 | char8 | ✅ |
| char16_t | uint16 | char16 | ✅ |
| int8_t | int8 | int8 | ✅ |
| int16_t | int16 | int16 | ✅ |
| int32_t | int32 | int32 | ✅ |
| int64_t | int64 | int64 | ✅ |
| uint8_t | uint8 | uint8 | ✅ |
| uint16_t | uint16 | uint16 | ✅ |
| uint32_t | uint32 | uint32 | ✅ |
| uint64_t | uint64 | uint64 | ✅ |
| uintptr_t | uintptr | ptr64 | ✅ |
| uintptr_t | uintptr | ptr32 | ✅ |
| float | float32 | float | ✅ |
| double | float64 | double | ✅ |
| void* | named func type | function | ❌ |
| plg::string | string | string | ✅ |
| plg::any | any | any | ✅ |
| plg::vector<bool> | []bool | bool[] | ✅ |
| plg::vector<char> | []int8 | char8[] | ✅ |
| plg::vector<char16_t> | []uint16 | char16[] | ✅ |
| plg::vector<int8_t> | []int8 | int8[] | ✅ |
| plg::vector<int16_t> | []int16 | int16[] | ✅ |
| plg::vector<int32_t> | []int32 | int32[] | ✅ |
| plg::vector<int64_t> | []int64 | int64[] | ✅ |
| plg::vector<uint8_t> | []uint8 | uint8[] | ✅ |
| plg::vector<uint16_t> | []uint16 | uint16[] | ✅ |
| plg::vector<uint32_t> | []uint32 | uint32[] | ✅ |
| plg::vector<uint64_t> | []uint64 | uint64[] | ✅ |
| plg::vector<uintptr_t> | []uintptr | ptr64[] | ✅ |
| plg::vector<uintptr_t> | []uintptr | ptr32[] | ✅ |
| plg::vector<float> | []float32 | float[] | ✅ |
| plg::vector<double> | []float64 | double[] | ✅ |
| plg::vector<plg::string> | []string | string[] | ✅ |
| plg::vector<plg::any> | []any | any[] | ✅ |
| plg::vector<plg::vec2> | []plugify.Vector2 | vec2[] | ✅ |
| plg::vector<plg::vec3> | []plugify.Vector3 | vec3[] | ✅ |
| plg::vector<plg::vec4> | []plugify.Vector4 | vec4[] | ✅ |
| plg::vector<plg::mat4x4> | []plugify.Matrix4x4 | mat4x4[] | ✅ |
| plg::vec2 | plugify.Vector2 | vec2 | ✅ |
| plg::vec3 | plugify.Vector3 | vec3 | ✅ |
| plg::vec4 | plugify.Vector4 | vec4 | ✅ |
| plg::mat4x4 | plugify.Matrix4x4 | mat4x4 | ✅ |
Exporting Functions in Go
To export a function, mark it with a //plugify:export Name comment. The function must be exported in Go terms (start with a capital letter). The go-plugify generator then writes a cgo wrapper __Name for it and describes the function in the plugin manifest, where funcName is the name of that wrapper.
Using Generator to Simplify Function Export
The generator from go-plugify (called from your generator.go, see below) simplifies the process of exporting Go functions by:
- Scanning the Plugin Package: It finds functions with the
//plugify:exportcomment. - Creating the Manifest: It writes the
.ppluginmanifest with the signatures of these functions. - Generating Files: It writes
autoexports.goandautoexports.hwith the cgo wrappers that convert Plugify types to Go types.
This tool eliminates the need for manual marshalling, making it easier for developers to integrate their Go plugins into the Plugify ecosystem.
Basic Example
Here’s a simple example of exporting a function in a Go plugin:
Function Definition
Plugin Manifest
The generator describes the function in the methods section of the manifest:
Generated Code
The generated autoexports.go contains the wrapper that other plugins call:
This generated code handles the conversion of Plugify types to Go types and ensures the function can be called from other plugins.
Advanced Example: Exporting Complex Functions
Here’s an example of exporting a function with complex parameter and return types:
Function Definition
Plugin Manifest
Generated Code
Strings and slices arrive as Plugify containers; the wrapper converts them to Go values and the result back:
This generated code handles the conversion of Plugify types to Go types and ensures the function can be called from other plugins.
Exporting Functions with References
Plugify supports reference parameters (also known as "out" or "inout" parameters) that allow functions to modify values and return them to the caller. In Go, reference parameters are implemented using pointers.
Function Definition with Reference Parameters
Plugin Manifest with Reference Parameters
In the manifest, parameters passed by reference are marked with "ref": true:
Generated Code for Reference Parameters
The generator will create wrapper functions that handle pointer marshalling:
Reference Parameter Support
Reference parameters work with most Plugify types as shown in the "Ref Support" column of the type mapping table. The following types do not support references:
void(cannot be passed by reference)function(callback/delegate types)
All other types including primitives, strings, slices, and structs support reference parameters via pointers.
Handling Callbacks
Plugify allows you to export functions that accept callbacks as parameters. The callback type must be a named Go function type:
Function Definition
Plugin Manifest
The generator puts the callback signature into prototypes and refers to it by name:
Generated Code
The wrapper turns the native function pointer into a value of your Go function type:
Automating Manifest and Export Generation
The manifest and the export code are not written by hand: you mark functions with //plugify:export Name comments and run go generate. The generator parses your package and writes:
- Plugin Manifest (
.ppluginfile) with all exported methods - Autoexport Files (
autoexports.goandautoexports.h) with marshalling code
Benefits of Automated Generation
- No Manual JSON Writing: Function signatures are automatically extracted from your code
- Complete Type Information: Parameter types and return types are automatically mapped
- Automatic Marshalling: Export wrappers with proper type conversion are generated
- Reduced Errors: Eliminates typos and type mismatches between code and manifest
- Easy Maintenance: Changes to function signatures are automatically reflected
Setup: Creating Your Generator
The generator is part of the go-plugify package, but it is started from your own generator.go, which calls plugify.Generate(). The Go plugin template already contains this file:
The //go:build ignore line keeps generator.go out of the plugin build. The //go:generate directive that starts it goes into one of your plugin's source files, for example main.go:
description, author, website and license are required fields of the manifest: if you leave these flags out, Plugify rejects the generated manifest.
Using the //plugify:export Comment
Mark your exported functions with the //plugify:export FuncName comment directive:
Running the Generator
Run the generator using the go generate command:
Or run it manually with the same flags:
Then build the plugin as usual (go build -buildmode=c-shared).
How It Works
- During Generation: The Go parser analyzes your package looking for
//plugify:exportcomments - Type Analysis: It extracts function signatures and maps Go types to Plugify types (e.g.,
int32→int32,[]string→string[]) - Manifest Generation: A
.ppluginfile is created with all exported methods - Export Code Generation:
autoexports.goandautoexports.hfiles are generated with proper marshalling code
Best Practices
- Use
//plugify:export: Mark functions for automated generation with the//plugify:export FuncNamecomment directive. - Create a Generator File: Set up your own
generator.gofile that callsplugify.Generate()for automated manifest and export generation. - Follow Type Conventions: Adhere to Plugify's type conventions for parameters and return values.
- Document Your Functions: Use Go doc comments to clearly document the purpose, parameters, and return values of exported functions.
- Use
go generate: Rungo generateto automatically regenerate manifest and export files after making changes. - Test Thoroughly: Test your exported functions to ensure they work as expected when called by other plugins.
- Keep Generated Files in Sync: Regenerate after any changes to function signatures to maintain consistency.
Conclusion
Exporting functions in Go plugins is streamlined with the generator from go-plugify. By marking your functions with //plugify:export comments and running go generate, you get both the plugin manifest and the export code with proper type marshalling. This eliminates manual JSON writing and reduces errors, making it easier to create robust and interoperable plugins. For callbacks, the generator handles the complex marshalling code for you.