面试题答案
一键面试1. 错误类型
- C函数返回错误码:C函数通常通过返回特定的错误码来表示操作失败。例如,
open
函数在失败时返回 -1。 - 内存分配失败:C的
malloc
等内存分配函数可能因为系统内存不足而失败,返回NULL
。 - 未定义行为:比如在C代码中访问越界内存,在Rust调用时也可能导致程序崩溃。
- 类型不匹配:Rust和C的数据类型表示可能不同,例如不同平台下
int
的大小不同,如果传递参数或返回值时类型不匹配,会导致错误。
2. 在Rust中捕获并处理错误
C函数返回错误码
假设我们有一个简单的C函数add_numbers
,如果输入的数字为负数则返回错误码:
// add_numbers.c
#include <stdio.h>
// 返回两个数的和,如果输入为负数返回 -1
int add_numbers(int a, int b) {
if (a < 0 || b < 0) {
return -1;
}
return a + b;
}
在Rust中调用:
extern crate libc;
use std::ffi::CString;
use std::os::raw::c_int;
extern "C" {
fn add_numbers(a: c_int, b: c_int) -> c_int;
}
fn main() {
let result = unsafe { add_numbers(2, 3) };
if result == -1 {
eprintln!("Error: negative numbers not allowed");
} else {
println!("The result is: {}", result);
}
}
内存分配失败
考虑C中的malloc
函数,假设我们有一个C函数allocate_memory
封装了malloc
:
// allocate_memory.c
#include <stdlib.h>
void* allocate_memory(size_t size) {
return malloc(size);
}
在Rust中调用:
extern crate libc;
use std::ffi::CString;
use std::os::raw::{c_void, c_size_t};
extern "C" {
fn allocate_memory(size: c_size_t) -> *mut c_void;
}
fn main() {
let size: c_size_t = 1024;
let ptr = unsafe { allocate_memory(size) };
if ptr.is_null() {
eprintln!("Memory allocation failed");
} else {
// 使用分配的内存
unsafe { libc::free(ptr as *mut _) };
}
}
处理未定义行为和类型不匹配
通过在Rust中严格检查输入输出类型,以及使用安全的Rust惯用法来避免未定义行为。例如,在传递字符串给C函数时,确保字符串的表示正确。
// print_string.c
#include <stdio.h>
#include <string.h>
void print_string(const char* str) {
printf("%s\n", str);
}
在Rust中调用:
extern crate libc;
use std::ffi::CString;
use std::os::raw::c_char;
extern "C" {
fn print_string(str: *const c_char);
}
fn main() {
let rust_string = "Hello, Rust calling C!";
let c_string = CString::new(rust_string).expect("Failed to convert string");
unsafe { print_string(c_string.as_ptr()) };
}
通过以上方法,在Rust调用C代码时,可以有效地捕获和处理各种可能出现的错误,保证程序的健壮性。