ModularM
Modular3y ago
1 reply
DisappointingSalad

Is StringLiteral intended for handling c strings?

Suppose I have c-library function in thing.c that returns a string. What datatype should I use to represent the return type for a FFI binding in a Mojo program?
char* returnABCD(void) {
    // Returns (pointer to a) null-terminated string 
    return "abcd";
}

Compile to shared library: clang -shared -o libThing.so thing.c

Option 1: UInt8 pointer

If I specify that the return type is a char/uint8 pointer, then I need to write a function parseCharArrayToString that builds a string by loading each character until a null terminator is reached. This approach works fine.
from sys import ffi

alias c_func_char_ptr = fn() -> Pointer[UInt8]

fn parseCharArrayToString(ptr: Pointer[UInt8]) -> String:
    """Extracts characters from a char array until null terminator.
    """
    var count = 0
    var c_str: String = ""
    while True:
        let ascii_code = int(ptr.load(count))
        if ascii_code == 0:
            break
        c_str = c_str + chr(ascii_code)
        count += 1
    return c_str

fn main():
    let lib_path = "./libThing.so"
    let lib_handle = ffi.DLHandle(lib_path)
    let func_handle = lib_handle.get_function[c_func_char_ptr]('returnABCD')

    let text = parseCharArrayToString(func_handle())
    print(text)


Option 2: StringLiteral (Broken?)

I could instead specify the return type to be a StringLiteral.
from sys import ffi

alias c_func_string_literal = fn() -> StringLiteral

fn main():
    let lib_path = "./libThing.so"
    let lib_handle = ffi.DLHandle(lib_path)
    let func_handle = lib_handle.get_function[c_func_string_literal]('returnABCD')

    let text = func_handle()
    print(text)

The value printed by the above program is correct. However, the length of the StringLiteral is wrong.
> print(len(text))
A very big number (e.g. 4930616832) (number changes between runs)

Is something wrong with the StringLiteral implementation, or am I misunderstanding how it can be used?
Was this page helpful?