Sign in

    This version of the module is deprecated: This package is deprecated. moonbit-community/ffi should be preferred.

    ffi

    MoonBit Foreign Function Interface.

    ffi
    bindings
    abi
    utils
    Download zip
    Author
    Version
    0.1.10
    License
    MIT
    Last updated
    last year
    Downloads
    25K

    #MoonBit FFI

    A lightweight utility library for converting between C‐style null-terminated byte strings (Bytes) and MoonBit String values.

    Build Status

    #Features

    • from_cstr: Convert a null-terminated Bytes to a MoonBit String (drops the \x00 terminator).
    • to_cstr: Convert a MoonBit String to null-terminated Bytes.

    #Installation

    Add justjavac/ffi to your dependencies:

    moon update moon add justjavac/ffi

    #Usage

    // Convert Bytes → String
    let data = b"Hello, world!\x00"
    let s = @ffi.from_cstr(data)
    assert_eq!(s, "Hello, world!")

    // Convert String → Bytes
    let cstr = @ffi.to_cstr("Hello, world!")
    assert_eq!(cstr, data)

    #Supported Backends

    • Wasm & WasmGC
    • JavaScript
    • Native
    • LLVM

    #Development

    Build the library and run tests (including docs):

    moon build moon test --doc

    #License

    This project is licensed under the MIT License. © justjavac

    from_cstr

    fn from_cstr(b : Bytes) -> String
    Converts a null-terminated byte array to a String.

    This function takes a C-style null-terminated byte array and converts it to a MoonBit String. It validates that the input is properly null-terminated and removes the terminating null byte during conversion.

    The function performs the following operations:
    1. Validates that the last byte is a null terminator (\x00)
    2. Removes the null terminator from the byte array
    3. Converts each byte to its corresponding character
    4. Constructs a MoonBit String from the character array

    Parameters

    • b: A byte array that must be null-terminated (ending with \x00)

    Returns

    A String representation of the byte array, excluding the null terminator

    Example

    // Basic conversion
    let c_str = b"Hello, world!\x00"
    let moonbit_str = @ffi.from_cstr(c_str)
    // moonbit_str equals "Hello, world!"

    // UTF-8 text conversion
    let utf8_c_str = b"Caf\xc3\xa9\x00" // "Café" in UTF-8 with null terminator
    let utf8_str = @ffi.from_cstr(utf8_c_str)
    // utf8_str equals "Café"

    // Empty string conversion
    let empty_c_str = b"\x00"
    let empty_str = @ffi.from_cstr(empty_c_str)
    // empty_str equals ""

    Safety

    • Validation: The function aborts with an error message if the input is not null-terminated
    • Memory safety: No buffer overflows as the function respects byte array boundaries
    • Character encoding: Assumes valid UTF-8 byte sequences for proper character conversion

    Error Conditions

    The function will abort execution if:
    • The input byte array is empty
    • The last byte is not \x00 (null terminator)
    • The input is not a valid null-terminated C string

    from_wstr_lossy

    fn from_wstr_lossy(b : Bytes) -> String
    Converts a null-terminated UTF-16 byte array to a String.

    This function handles UTF-16 encoded wide strings commonly used on Windows. It expects the byte array to be null-terminated (ending with two zero bytes) and uses lossy conversion to handle any invalid UTF-16 sequences gracefully.

    The function performs the following operations:
    1. Validates that the input is properly null-terminated (last two bytes are zero)
    2. Removes the null termination bytes
    3. Uses the UTF-16 decoder to convert bytes to a string
    4. Applies lossy conversion to handle invalid sequences

    Parameters

    • b: A byte array containing UTF-16 encoded data, expected to be null-terminated with two zero bytes (\x00\x00)

    Returns

    A String representation of the UTF-16 data, excluding the null terminator. Invalid UTF-16 sequences are replaced with the Unicode replacement character (�).

    Example

    // Basic ASCII conversion
    let wide_hello = b"\x48\x00\x65\x00\x6c\x00\x6c\x00\x6f\x00\x00\x00"
    let str_hello = @ffi.from_wstr_lossy(wide_hello)
    // str_hello equals "Hello"

    // Unicode characters (Chinese text)
    let wide_chinese = b"\x16\x4e\x96\x75\x00\x00" // "世界" in UTF-16LE
    let str_chinese = @ffi.from_wstr_lossy(wide_chinese)
    // str_chinese equals "世界"

    // Empty string
    let empty_wide = b"\x00\x00"
    let empty_str = @ffi.from_wstr_lossy(empty_wide)
    // empty_str equals ""

    // Mixed content
    let mixed = b"\x48\x00\x65\x00\x6c\x00\x6c\x00\x6f\x00\x2c\x00\x20\x00\x16\x4e\x96\x75\x21\x00\x00\x00"
    let mixed_str = @ffi.from_wstr_lossy(mixed)
    // mixed_str equals "Hello, 世界!"

    Safety and Error Handling

    • Null termination check: Aborts if the input is not properly null-terminated
    • Lossy conversion: Invalid UTF-16 sequences are replaced rather than causing errors
    • Memory safety: Respects byte array boundaries and validates input length
    • Graceful degradation: Continues processing even with some invalid data

    UTF-16 Specifics

    • Byte order: Assumes system byte order (little-endian on Windows x86/x64)
    • Surrogate pairs: Properly handles characters requiring surrogate pairs
    • BOM handling: Does not expect or process Byte Order Mark (BOM)
    • Alignment: Input should be properly aligned for 16-bit values

    Error Conditions

    The function will abort execution if:
    • The input byte array has fewer than 2 bytes
    • The last two bytes are not both \x00 (proper null termination)
    • The input is not a valid null-terminated wide string

    to_cstr

    fn to_cstr(s : String) -> Bytes
    Converts a String to a C-style null-terminated byte array.

    This function takes a MoonBit String and converts it to a null-terminated byte array suitable for passing to C functions via FFI. It appends a null terminator (\x00) to ensure C compatibility.

    The function performs the following operations:
    1. Converts the string to a character array
    2. Appends a null character (\u{0000}) to the array
    3. Converts each character to its byte representation
    4. Returns the resulting byte array

    Parameters

    • s: A String that will be converted to a null-terminated byte array

    Returns

    A Bytes object containing the null-terminated byte representation of the string. The returned bytes are suitable for passing to C functions that expect C-style strings.

    Example

    // Basic conversion
    let moonbit_str = "Hello, world!"
    let c_str = @ffi.to_cstr(moonbit_str)
    // c_str equals b"Hello, world!\x00"

    // Empty string conversion
    let empty_str = ""
    let empty_c_str = @ffi.to_cstr(empty_str)
    // empty_c_str equals b"\x00"

    // UTF-8 text conversion
    let utf8_str = "Café"
    let utf8_c_str = @ffi.to_cstr(utf8_str)
    // utf8_c_str contains UTF-8 bytes: b"Caf\xc3\xa9\x00"

    // Using with FFI functions
    // extern "C" fn printf(format : Bytes, ...) -> Int = "printf"
    // let message = "Hello from MoonBit!"
    // let result = printf(@ffi.to_cstr("%s\n"), @ffi.to_cstr(message))

    Memory Management

    • Safe allocation: The function creates a new byte array, no memory leaks
    • Automatic sizing: Automatically calculates the correct buffer size
    • Null termination: Always ensures proper null termination for C compatibility

    Character Encoding

    • UTF-8 compatible: Properly handles UTF-8 encoded characters
    • Byte-by-byte: Each character is converted to its byte representation
    • C standard: Results are compatible with standard C string functions

    Use Cases

    • FFI calls: Passing strings to C functions that expect char* parameters
    • File operations: Working with C file APIs that use string paths
    • System calls: Interfacing with POSIX APIs that require C strings
    • Library integration: Calling third-party C libraries from MoonBit

    to_wstr

    fn to_wstr(s : String) -> Bytes
    Converts a String to a null-terminated UTF-16 byte array.

    This function converts a MoonBit string to UTF-16 encoding with null termination, which is the format commonly used for Windows wide string APIs. The resulting byte array can be passed directly to Windows API functions that expect wide strings.

    The function performs the following operations:
    1. Appends a null terminator to the input string
    2. Uses the UTF-16 encoder to convert the string to bytes
    3. Returns the encoded byte array with proper null termination

    Parameters

    • s: A String that will be converted to a null-terminated UTF-16 byte array

    Returns

    A Bytes object containing the UTF-16 encoded representation with null termination. The result is suitable for passing to Windows API functions that expect wide strings.

    Example

    // Basic ASCII conversion
    let hello_str = "Hello"
    let hello_wide = @ffi.to_wstr(hello_str)
    // hello_wide contains: b"\x48\x00\x65\x00\x6c\x00\x6c\x00\x6f\x00\x00\x00"

    // Unicode characters (Chinese text)
    let chinese_str = "世界"
    let chinese_wide = @ffi.to_wstr(chinese_str)
    // chinese_wide contains UTF-16 encoded bytes for "世界" with null termination

    // Empty string
    let empty_str = ""
    let empty_wide = @ffi.to_wstr(empty_str)
    // empty_wide contains: b"\x00\x00"

    // Mixed content with emojis
    let mixed_str = "Hello, 世界! 🌍"
    let mixed_wide = @ffi.to_wstr(mixed_str)
    // mixed_wide contains UTF-16 encoded bytes with null termination

    // Using with Windows API
    // extern "C" fn CreateFileW(
    // lpFileName : Bytes,
    // dwDesiredAccess : Int,
    // dwShareMode : Int,
    // lpSecurityAttributes : Int64,
    // dwCreationDisposition : Int,
    // dwFlagsAndAttributes : Int,
    // hTemplateFile : Int64
    // ) -> Int64 = "CreateFileW"
    //
    // let file_handle = CreateFileW(
    // @ffi.to_wstr("C:\\path\\to\\file.txt"),
    // 0x80000000, // GENERIC_READ
    // 1, // FILE_SHARE_READ
    // 0, // No security attributes
    // 3, // OPEN_EXISTING
    // 0x80, // FILE_ATTRIBUTE_NORMAL
    // 0 // No template file
    // )

    UTF-16 Encoding Details

    • Character representation: Each character encoded as one or two 16-bit units
    • Byte order: Uses system byte order (little-endian on Windows x86/x64)
    • Surrogate pairs: Automatically handles characters outside the Basic Multilingual Plane
    • Null termination: Always appends two zero bytes for C API compatibility

    Memory and Performance

    • Memory allocation: Creates a new byte array with proper sizing
    • Encoding efficiency: Uses optimized UTF-16 encoding implementation
    • Size calculation: Automatically determines correct buffer size
    • No leaks: Memory management handled by MoonBit runtime

    Use Cases

    • Windows API calls: Perfect for functions ending in 'W' (wide character versions)
    • File operations: Windows file paths and names
    • Registry operations: Windows registry keys and values
    • UI operations: Window titles, menu items, dialog text
    • COM interfaces: Component Object Model string parameters

    Character Support

    • ASCII: All ASCII characters (0-127) encoded efficiently
    • Latin scripts: Full support for European languages
    • CJK characters: Chinese, Japanese, Korean character support
    • Emojis: Modern Unicode emojis and symbols
    • Mathematical symbols: Unicode mathematical and technical symbols

    Source Files