Returning a struct containing a String from Rust to Julia #209
-
|
Hello again I am trying to write a Rust function that returns a struct with a string as a field, but can't seem to get it to work. Reflection gives me a Rust struct like this: #[repr(C)]
#[derive(Clone, Debug, Unbox, ValidLayout, Typecheck, ValidField, ConstructType, CCallArg)]
#[jlrs(julia_type = "Main.TestModule.StringFloat")]
pub struct StringFloat<'scope> {
pub s: Option<WeakString<'scope>>,
pub f: f64,
}I can't derive fn get_string_float() -> TypedValueRet<StringFloat<'static>> {
match weak_handle!() {
Ok(handle) => {
let string_float = StringFloat {
s: Some(JuliaString::new(&handle, "Test")),
f: 1.0,
};
TypedValue::try_new_with::<StringFloat, _>(handle, string_float)
.unwrap()
.leak()
}
_ => panic!("not called from Julia"),
}
}
Thanks in advance, and thanks for all of the work put into the library! Full code if relevant: Rust codeuse jlrs::{
data::{
layout::typed_layout::TypedLayout,
managed::{
string::WeakString,
value::typed::{TypedValue, TypedValueRet},
},
},
prelude::*,
weak_handle,
};
#[repr(C)]
#[derive(Clone, Debug, Unbox, ValidLayout, Typecheck, ValidField, ConstructType, CCallArg)]
#[jlrs(julia_type = "Main.TestModule.StringFloat")]
pub struct StringFloat<'scope> {
pub s: Option<WeakString<'scope>>,
pub f: f64,
}
fn get_string_float() -> TypedValueRet<StringFloat<'static>> {
match weak_handle!() {
Ok(handle) => {
let string_float = StringFloat {
s: Some(JuliaString::new(&handle, "Test")),
f: 1.0,
};
TypedValue::try_new_with::<StringFloat, _>(handle, string_float)
.unwrap()
.leak()
}
_ => panic!("not called from Julia"),
}
}
julia_module! {
become julia_module_tutorial_init_fn;
fn get_string_float() -> TypedValueRet<StringFloat<'static>>;
}Julia codemodule TestModule
using JlrsCore.Wrap
struct StringFloat
s::String
f::Float64
end
@wrapmodule("./target/debug/libjulia_lib", :julia_module_tutorial_init_fn)
function __init__()
@initjlrs
end
end |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
|
I was indeed missing something crucial; #[repr(C)]
pub struct StringFloat {
pub s: ValueRet,
pub f: f64,
}
unsafe impl Send for StringFloat {}
unsafe impl Sync for StringFloat {}
unsafe impl ForeignType for StringFloat {
fn mark(ptls: PTls, data: &Self) -> usize {
// Safety: We mark all referenced managed data.
unsafe { mark_queue_obj(ptls, data.s) as usize }
}
}
impl StringFloat {
fn get_s(&self) -> ValueRet {
self.s
}
fn get_f(&self) -> f64 {
self.f
}
}
fn get_string_float() -> TypedValueRet<StringFloat> {
match weak_handle!() {
Ok(handle) => {
let s = unsafe { JuliaString::new(&handle, "Test").as_value() }
.as_ref()
.leak();
let string_float = StringFloat { s, f: 1.0 };
TypedValue::new(handle, string_float).leak()
}
_ => panic!("not called from Julia"),
}
}
julia_module! {
become julia_module_tutorial_init_fn;
struct StringFloat;
in StringFloat fn get_s(&self) -> ValueRet;
in StringFloat fn get_f(&self) -> f64;
fn get_string_float() -> TypedValueRet<StringFloat>;
}(I downgraded from the repo version back to the release). There's no (reasonable) way to implement |
Beta Was this translation helpful? Give feedback.
-
|
You must not implement |
Beta Was this translation helpful? Give feedback.
You must not implement
ForeignTypehere. The only supported way to construct non-isbits types is by calling their constructor. You can call a constructor of aDataTypeby converting it to aValueand calling it as a function.