2

I have an static mutable value:

static mut ADDRESS: &'static str = "";

It is global, not in any function.

And now i have a problem:
I have functions that read this value, them working correctly, but when i tried to make function that change this value from arguments - it start crying that value "does't live long enough".

#[no_mangle]
pub unsafe extern fn Java_Rust_setAddress(
    env: JNIEnv,
    _: JClass,
    address: JString
) {
    let input: String = env.get_string(address).expect("Couldn't get java string!").into();
    ADDRESS = &input /Error there/
}

What can i do with it? Transfering address in each case is not a variant, i really need a simple global variable.

ADDRESS = input.as_str()

not works too.

But

ADDRESS = "Something"

works good.

4
  • 3
    Your String will get dropped after your function is finished. A reference to it can't go in a static variable with a static lifetime. Commented Dec 12, 2020 at 15:49
  • Does this answer your question? How do I create a global, mutable singleton? Commented Dec 12, 2020 at 15:49
  • @Aplet123 it's not critical for me make ADDRESS value from variable or from variable value. I can't believe that programming language made in 2010 and with so big community don't have so simple functionality as i need. Commented Dec 12, 2020 at 15:57
  • The problem is that static mutable data are not simple. Commented Dec 12, 2020 at 17:46

1 Answer 1

2

Your String will get dropped after the function is finished. Therefore, you cannot store a reference to in a static variable:

ADDRESS = &input;
       // ^^^^^^ input does not live long enough
       // ADDRESS requires that `input` is borrowed for `'static`
}
// < `input` dropped here while still borrowed by ADDRESS

Instead, you need to store a global heap-allocated String. There are a couple ways to have a global heap-allocated variable as explained here. In your case, you can use a thread_local global static variable and wrap the string in a Cell, which provides mutability:

use std::cell::Cell;

thread_local!(static ADDRESS: Cell<String> = Cell::new("".to_string()));

#[no_mangle]
pub unsafe extern fn Java_Rust_setAddress(
    env: JNIEnv,
    _: JClass,
    address: JString
) {
    let input: String = env.get_string(address).expect("Couldn't get java string!").into();
    ADDRESS.with(|address| address.set(input));
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.