Я пытаюсь вызвать некоторый код Rust из C и получить результат обратно, но я получаю ошибку «Указатель освобожден не был выделен» на стороне Rust.
Я хочу вызвать функцию hex::encode
.Я передаю указатель на некоторые байты, длину и указатель, выделенный в C с помощью malloc.Я хочу, чтобы результат преобразования был передан обратно по этому указателю.
Функция Rust:
extern crate libc;
use hex;
use std::ffi::CString;
use std::os::raw::c_char;
use std::vec::Vec;
use std::{ffi, ptr, slice};
#[no_mangle]
pub extern "C" fn bytes_to_hex_string(bp: *mut u8, bp_size: usize, sp: *mut c_char) -> i8 {
println!("1");
let p_vec = unsafe { Vec::from_raw_parts(bp, bp_size, bp_size + 1) };
println!("2");
let str = hex::encode(p_vec);
println!("3");
let bytes = str.as_bytes();
println!("4");
let cs = CString::new(bytes).unwrap(); // will fail if bytes has "gap" (null) in sequence
println!("5");
unsafe {
libc::strcpy(sp, cs.as_ptr());
}
println!("6");
return 1;
}
Вызывается из этого кода C:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int8_t bytes_to_hex( uint8_t *, unsigned int, char *);
int main() {
char *ptr = "Hello World!";
char *hex = (char *)malloc(1000);
printf("about to call....\n");
bytes_to_hex_string((uint8_t*)ptr,strlen(ptr),hex);
printf("about to print....\n");
printf("%s\n",hex);
printf("about to free....\n");
free(hex);
}
Когда я запускаюпрограмма:
$ ./a.out
about to call....
1
2
a.out(2941,0x7fffccae03c0) malloc: *** error for object 0x10afe2b80: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
Похоже, что код Rust внутри шестнадцатеричного ящика освобождает указатель ptr
, верно?
Есть ли способ как-то обойти это?Я бы предпочел, чтобы распределение и освобождение происходили в C, но я открыт для любых предложений, чтобы решить эту проблему!