Question about the FFI, unsafe_cstr_ptr, and PathLike

When calling into a dylib from mojo using the FFI, the char* I pass is seemingly freed before the c function receives it - the following code's output won't show the path. However, if I artificially "retain" the path_string until after the external call, it succeeds. It also succeeds if I use a string literal instead of a Path. Is this a bug or is this a misunderstanding on my part of the ASAP deconstruction?
#
# example.mojo
#

from os import PathLike
from pathlib import Path
from sys.ffi import DLHandle, C_char

fn main():
    var path = Path("path/to/file")
    call_external_function(path = path)

fn call_external_function(path: Path):
    var lib = DLHandle("lib/libcodecs.dylib")

    var external_function = lib.get_function[fn (path: UnsafePointer[C_char]) -> None]("external_function")

    var path_string = path.__fspath__()

    external_function(path = path_string.unsafe_cstr_ptr())
    
    # Artificially retain the var so it lives through the c call
    # var retained_ptr = path_string.unsafe_cstr_ptr()

    lib.close()


//
// lib.c
//
#include <stdlib.h>
#include <stdio.h>

__attribute__((visibility("default")))
void external_function(const char* path) {
    printf("path = %s\n", path);
}


Follow-up, if I replace the type of the fn arg with PathLike, the compiler throws could not deduce positional-only parameter #0 of callee '__fspath__'. I would think I should be able to use a PathLike here to get an __fspath__ without the explicit Path type, right?

Thanks!
Was this page helpful?