簡體   English   中英

Rust 字符串和 C 可變參數函數

[英]Rust Strings and C variadic functions

我需要將 Rust 字符串的向量傳遞給C 可變參數函數 但我無法弄清楚預期的( CString[u8] ..)格式是什么。

參考:

我的api16示例代碼版本:

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

api16版本的結果:

event_buffer: 'evento' 8
result_buffer: '' 8

我的生銹代碼:

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}\0\0\0\0\0\0" "\0PQ(�\u{7f}\0\0\0\0\0\0"

我已經嘗試使用CStringCStr ,就像這里一樣。

我究竟做錯了什么?

你在 Rust 版本中做錯了很多事情。 對於前兩個參數,您打算將指針傳遞到一個位置,該位置可以保存指向字節緩沖區的單個指針。 相反,您傳遞了一個指向字節緩沖區的指針,因此指針被寫入該緩沖區,這不是您想要的。

其次, id_count參數對應於您作為可變參數傳遞的字符串數,而不是單個可變字符串的長度,這意味着您的 C 代碼只是讀取一堆未初始化的內存,這絕對不是您想要的. 此外,該字符串確實需要以 null 結尾,並且它不在您的示例中,您確實需要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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM