Rust string和C可变函数



我需要传递一个Rust字符串的向量到一个C可变函数。但是我不知道期望的(CString,[u8]..)格式是什么。

引用:

  • API引用:isc_event_block
  • 我的外部C声明:ibase
  • 如何调用:que_events
  • C示例:api16
  • API实现:isc_event_block

我的api16示例代码版本:

strcpy (ids[0], "evento");
length = (short)  isc_event_block((char **) &event_buffer, (char **) &result_buffer, 1, ids[0], 0);
printf("event_buffer: '%s' %dn", event_buffer, sizeof(event_buffer));
printf("result_buffer: '%s' %dn", result_buffer, sizeof(result_buffer));

api16版本结果:

event_buffer: 'evento' 8
result_buffer: '' 8
我的Rust代码:
let mut event_buffer: Vec<u8> = Vec::with_capacity(256);
let mut result_buffer: Vec<u8> = Vec::with_capacity(256);
let mut len = 0;
let names = "evento".to_string();
unsafe {
len = self.ibase.isc_event_block()(
event_buffer.as_mut_ptr() as *mut _,
result_buffer.as_mut_ptr() as *mut _,
names.len() as u16,
names.as_ptr()
);
event_buffer.set_len(len as usize);
result_buffer.set_len(len as usize);
}
println!("{:?} {:?}", len, names);
println!("{:x?} {:x?}", event_buffer, result_buffer);
println!("{:?} {:?}", String::from_utf8_lossy(&event_buffer.clone()), String::from_utf8_lossy(&result_buffer.clone()));

我的Rust代码结果:

12 ["evento"]
[e0, 4f, 51, 28, a8, 7f, 0, 0, 0, 0, 0, 0] [0, 50, 51, 28, a8, 7f, 0, 0, 0, 0, 0, 0]
"�OQ(�u{7f}" "PQ(�u{7f}"

我已经尝试使用CStringCStr,像这里。

我做错了什么?

你在rust版本中做错了很多事情。对于前两个参数,您打算传递一个指向一个位置的指针,该位置可以保存指向字节缓冲区的单个指针。相反,你传递了一个指向字节缓冲区的指针,所以指针被写入缓冲区,这不是你想要的。

其次,id_count参数对应于作为可变参数传递的字符串的数量,而不是单个可变字符串的长度,这意味着您的c代码只是读取了一堆未初始化的内存,这绝对不是您想要的。此外,该字符串确实需要以空结束,并且它不在您的示例中,您确实需要CString。你真正想要的是这样的东西:

use std::ffi::{c_char, c_long, c_ushort, CStr, CString};
use std::ptr;
use std::slice;
use std::str;
fn main() {
let mut event_buffer = ptr::null_mut();
let mut result_buffer = ptr::null_mut();
let names = CString::new("evento").unwrap();
let len = unsafe {
isc_event_block(
&mut event_buffer,
&mut result_buffer,
1,
names.as_ptr() as *mut c_char,
)
};
debug_assert!(!event_buffer.is_null() && !result_buffer.is_null());
let event_slice = unsafe { slice::from_raw_parts(event_buffer.cast(), len as usize) };
let result_slice = unsafe { slice::from_raw_parts(event_buffer.cast(), len as usize) };
let event_str = str::from_utf8(event_slice).unwrap();
let result_str = str::from_utf8(result_slice).unwrap();
println!("event: {event_str}");
println!("result: {result_str}");
}

游乐场

添加一个简单的存根来打印传入的字符串,并将几个字符串写入缓冲区,我得到了这个:

"evento"
event: some events
result: some events

相关内容

  • 没有找到相关文章

最新更新