Export Functions
Guide to export functions from your Rust plugin to be used by other language modules within Plugify.
In the Plugify ecosystem, Rust plugins can export functions to make them accessible to other plugins. This guide explains how to export functions in Rust and provides examples to help you integrate your plugins seamlessly.
Basic Type Mapping
The following table lists how types are exposed to the Rust API:
| C++ Type | Rust Type | Plugify Alias | Ref Support? |
|---|---|---|---|
| void | () | void | ❌ |
| bool | bool | bool | ✅ |
| char | i8 | char8 | ✅ |
| char16_t | u16 | char16 | ✅ |
| int8_t | i8 | int8 | ✅ |
| int16_t | i16 | int16 | ✅ |
| int32_t | i32 | int32 | ✅ |
| int64_t | i64 | int64 | ✅ |
| uint8_t | u8 | uint8 | ✅ |
| uint16_t | u16 | uint16 | ✅ |
| uint32_t | u32 | uint32 | ✅ |
| uint64_t | u64 | uint64 | ✅ |
| uintptr_t | usize | ptr64 | ✅ |
| uintptr_t | usize | ptr32 | ✅ |
| float | f32 | float | ✅ |
| double | f64 | double | ✅ |
| void* | *const c_void | function | ❌ |
| plg::string | Str | string | ✅ |
| plg::any | Any | any | ✅ |
| plg::vector<bool> | Arr<bool> | bool[] | ✅ |
| plg::vector<char> | Arr<i8> | char8[] | ✅ |
| plg::vector<char16_t> | Arr<u16> | char16[] | ✅ |
| plg::vector<int8_t> | Arr<i8> | int8[] | ✅ |
| plg::vector<int16_t> | Arr<i16> | int16[] | ✅ |
| plg::vector<int32_t> | Arr<i32> | int32[] | ✅ |
| plg::vector<int64_t> | Arr<i64> | int64[] | ✅ |
| plg::vector<uint8_t> | Arr<u8> | uint8[] | ✅ |
| plg::vector<uint16_t> | Arr<u16> | uint16[] | ✅ |
| plg::vector<uint32_t> | Arr<u32> | uint32[] | ✅ |
| plg::vector<uint64_t> | Arr<u64> | uint64[] | ✅ |
| plg::vector<uintptr_t> | Arr<usize> | ptr64[] | ✅ |
| plg::vector<uintptr_t> | Arr<usize> | ptr32[] | ✅ |
| plg::vector<float> | Arr<f32> | float[] | ✅ |
| plg::vector<double> | Arr<f64> | double[] | ✅ |
| plg::vector<plg::string> | Arr<Str> | string[] | ✅ |
| plg::vector<plg::any> | Arr<Any> | any[] | ✅ |
| plg::vector<plg::vec2> | Arr<Vec2> | vec2[] | ✅ |
| plg::vector<plg::vec3> | Arr<Vec3> | vec3[] | ✅ |
| plg::vector<plg::vec4> | Arr<Vec4> | vec4[] | ✅ |
| plg::vector<plg::mat4x4> | Arr<Mat4x4> | mat4x4[] | ✅ |
| plg::vec2 | Vec2 | vec2 | ✅ |
| plg::vec3 | Vec3 | vec3 | ✅ |
| plg::vec4 | Vec4 | vec4 | ✅ |
| plg::mat4x4 | Mat4x4 | mat4x4 | ✅ |
Exporting Functions in Rust
To export a function in a Rust plugin, you need to ensure that the function is visible to other plugins. This is done by using the #[unsafe(no_mangle)] attribute macro provided by the Plugify crate.
Key Points
- No-mangle: The macro automatically applies
#[no_mangle]to prevent name mangling. - Extern "C": Functions are exported with C linkage for cross-language compatibility.
- Parameter and Return Types: Use Plugify's native types for seamless integration.
Basic Example
Here's a simple example of exporting a function in a Rust plugin:
Function Definition
The #[unsafe(no_mangle)] attribute automatically handles:
- Exporting the function with C linkage
- Preventing name mangling
- Making the function visible to other plugins
Plugin Manifest Example
All exported functions must be described in the plugin's manifest file under the methods section. Here's an example manifest for a plugin that exports the add_numbers function:
Advanced Example: Exporting Complex Functions
Here's an example of exporting a function with complex parameter and return types:
Function Definition
Plugin Manifest
Exporting Functions with References
Rust allows you to export functions that take mutable references:
Function Definition
Plugin Manifest
Handling Callbacks
Plugify allows you to export functions that accept callbacks as parameters:
Function Definition
Plugin Manifest
Working with Enums
Rust enums can be exported to Plugify:
Enum Definition
Plugin Manifest with Enum
Important: Enums used in exported functions must have #[repr(u8)], #[repr(i32)], or similar to ensure proper ABI compatibility.
Best Practices
- Use unsafe with extern "C": Always use the
#[unsafe(no_mangle)]macro to export functions. - Follow Type Conventions: Use Plugify's native types for parameters and return values.
- Document Your Functions: Use Rust doc comments (
///) to document exported functions. - Keep Manifest Updated: Ensure the manifest accurately reflects your exported functions.
- Use repr for Enums: Always specify
#[repr(...)]for enums used in exported functions. - Test Thoroughly: Test your exported functions to ensure they work as expected when called by other plugins.
- Handle Errors Gracefully: Consider using
Result<T, E>types and convert errors appropriately.
Error Handling
When exporting functions that can fail, consider using a pattern like this:
Conclusion
Exporting functions in Rust plugins is straightforward when you follow Plugify's conventions and best practices. By using the #[unsafe(no_mangle)] attribute, adhering to type conventions, and maintaining accurate manifest files, you can create robust and interoperable plugins. Rust's type safety and ownership system provide additional guarantees that help prevent common errors in plugin development.