Как безопасно передать строку C ++ в Rust? - PullRequest
2 голосов
/ 16 июня 2020

У меня есть эта функция Rust:

pub extern "C" fn do_something(my_string: &str) {
    let s = String::from(my_string);
}

То, что я вызываю на C ++ следующим образом:

std::string my_string("hello");
do_something(my_string.c_str());

Подпись:

extern "C" void* do_something(const char*);

Я получаю эту ошибку прямо в строке String::from:

memory allocation of 127963177044160 bytes failedAborted (core dumped)

Я предполагаю, что это потому, что переданная строка не имеет \n, поэтому он пытается сделать строку максимально возможного размера.

Как чтобы безопасно передать std::string Rust?

Ответы [ 2 ]

8 голосов
/ 16 июня 2020

То, что я вызываю на C ++ следующим образом:

do_something(my_string.c_str());

Итак, на стороне C ++ вы вызываете функцию с C строкой как input (а не std::string, что является очень важным различием).

Это означает, что функция Rust должна принимать в качестве входных данных строку C, а &str определенно не является.

Таким образом, do_something следует объявить как:

pub extern "C" fn do_something(my_string: *const c_char) {

, после чего, как отмечает Jmb, вы можете использовать CStr, чтобы безопасно обернуть указатель.

5 голосов
/ 16 июня 2020

Тип &str не является безопасным для FFI. Я ожидал, что компилятор Rust выдаст предупреждение об этом. Срезы Rust состоят из указателя и длины и не имеют компоновки, совместимой с C ++ const char*.

Один из вариантов - иметь do_something, принимающий указатель и длину (*const u8 и usize соответственно), наберите std::slice::from_raw_parts, чтобы обменять их на &'a [u8], и позвоните std::str::from_utf8_unchecked, чтобы обменять это на &str. Вы должны обеспечить соблюдение условий безопасности, задокументированных вместе с каждой из этих функций, включая то, что строка содержит действительный код UTF-8.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...