Gohryt
Gohryt

Reputation: 517

Change static string value

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.

Upvotes: 2

Views: 1485

Answers (1)

Ibraheem Ahmed
Ibraheem Ahmed

Reputation: 13618

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));
}

Upvotes: 2

Related Questions