}
unsafe fn call_cstr(&self, args: &[Arg], _: &mut Arena) -> Result<Value, FfiError> {
- let ptr = unsafe { self.cif.call::<*mut c_char>(self.code_ptr, args) };
- Ok(Value::CString(unsafe { CStr::from_ptr(ptr) }.to_owned()))
+ let ptr = unsafe {
+ self.cif
+ .call::<Option<NonNull<c_char>>>(self.code_ptr, args)
+ };
+
+ if let Some(cstr) = ptr {
+ Ok(Value::CString(
+ unsafe { CStr::from_ptr(cstr.as_ptr()) }.to_owned(),
+ ))
+ } else {
+ Ok(Value::Number(Number::Fixnum(Fixnum::build_with(0))))
+ }
}
unsafe fn call_struct(
ArgValue::I64(a) => libffi::middle::arg(a),
ArgValue::F32(a) => libffi::middle::arg(a),
ArgValue::F64(a) => libffi::middle::arg(a),
- ArgValue::Ptr(ptr, _) => unsafe { std::mem::transmute::<*mut c_void, Arg>(*ptr) },
+ ArgValue::Ptr(ptr, _) => Arg::new(ptr),
ArgValue::Struct(s) => unsafe {
std::mem::transmute::<*mut c_void, Arg>(s.ptr.as_ptr())
},
fn as_ptr(&mut self) -> Result<*mut c_void, FfiError> {
match self {
- Value::CString(ref mut cstr) => Ok(&mut *cstr as *mut _ as *mut c_void),
+ Value::CString(ref mut cstr) => Ok(cstr.as_ptr().cast_mut().cast()),
Value::Number(Number::Fixnum(fixnum)) => Ok(std::ptr::with_exposed_provenance_mut(
fixnum.get_num() as usize,
)),
:- use_module(library(os)).
:- use_module(library(ffi)).
-test :-
+init :-
read(Body),
term_variables(Body, [LIB]),
Body,
use_foreign_module(LIB, [
'ffi_cstr_len'([cstr], u64),
- 'ffi_example_cstr'([], cstr)
- ]),
+ 'ffi_example_cstr'([], cstr),
+ 'ffi_null_cstr'([], cstr)
+ ]).
+
+test :-
ffi:'ffi_cstr_len'("Scryer Prolog", Len),
ffi:'ffi_example_cstr'(Str),
- write((Len-Str)).
+ ffi:'ffi_null_cstr'(Null),
+ ffi:'ffi_cstr_len'(0, MaxU64),
+ write((Len-Str-Null-MaxU64)).
-:- initialization(test).
+:- initialization((init,test)).
use std::ffi::CStr;
#[unsafe(no_mangle)]
- extern "C" fn ffi_cstr_len(c_str: *const core::ffi::c_char) -> u64 {
- unsafe { CStr::from_ptr(c_str) }.count_bytes() as u64
+ extern "C" fn ffi_cstr_len(c_str: Option<std::ptr::NonNull<core::ffi::c_char>>) -> u64 {
+ if let Some(c_str) = c_str {
+ unsafe { CStr::from_ptr(c_str.as_ptr()) }.count_bytes() as u64
+ } else {
+ u64::MAX
+ }
}
#[unsafe(no_mangle)]
extern "C" fn ffi_example_cstr() -> *const core::ffi::c_char {
c"Rust Lang".as_ptr()
}
+
+ #[unsafe(no_mangle)]
+ extern "C" fn ffi_null_cstr() -> *const core::ffi::c_char {
+ std::ptr::null()
+ }
"##,
);
load_module_test_with_input(
"tests-pl/ffi_cstr.pl",
format!("LIB={dynlib_path:?}."),
- r#"13-[R,u,s,t, ,L,a,n,g]"#,
+ format!(r#"13-[R,u,s,t, ,L,a,n,g]-0-{}"#, u64::MAX).as_str(),
);
}