UTF-8 strings across generated ABI wrappers
Documentation status: reference — see Maturity and evidence.
The generated native ABI contract already defines a concrete string convention. Strings are projected as UTF-8 null-terminated pointers at the native boundary.
The generator states these ownership rules explicitly:
- input string: UTF-8, caller-owned;
- output/return string: UTF-8, module-owned and released through the module
Freefunction; - in/out string: caller-owned on input, module-owned on output;
- the module must not retain input string pointers after the call.
Generated wrapper behavior
Generated native wrappers allocate UTF-8 result buffers and expose a module Free function. The same allocator symmetry is used for GetLastError: the caller receives a UTF-8 allocation, copies it, and releases it through the module.
The generated C# model projects source strings to string. Character pointers used as string signatures are also projected to string because the generated native wrapper performs the UTF-8 conversion.
String return values are decoded by generated .NET runtime code rather than surfaced as IntPtr to application code.
Important layering distinction
The generated wrapper contract supports UTF-8 strings, but not every generic executor or experimental bridge in the codebase necessarily implements every published value kind.
Therefore distinguish:
publication/generator support
!=
all execution bridges certified
This page is reference for the generated native ABI string convention. Bridge-specific pages must state their own execution subset.
Null and empty
The native generated convention is pointer-based and null-terminated. Bindings must preserve the semantic difference between a null reference where nullable and an empty string where the target API distinguishes them.
Application code should never own the native UTF-8 pointer directly. Generated/runtime infrastructure is responsible for encoding, copying, and release.
.NET projection
For .NET, the normal projection is string / nullable string. The binding should:
managed string
-> UTF-8 call-scoped buffer
-> native generated wrapper
-> Runtime
For a returned string:
Runtime
-> module-owned UTF-8 pointer
-> generated .NET runtime copies to string
-> module Free
Cross-topology note
RPC transports strings as transport values rather than exposing the native pointer. Semantic parity should be validated at the generated contract level, not by requiring the same physical representation locally and remotely.