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()
#
# 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);
}
//
// 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!
0 Replies
No replies yetBe the first to reply to this messageJoin

Did you find this page helpful?