c# - 当调用对象的方法也会破坏对象时,是否建议使用 SafeHandle?
问题描述
有一个 Rust 库提供了三个功能:
- 浮点向量的构造函数
- 将数字推送到向量的函数
- 对向量求和的函数
像这样:
#[no_mangle]
pub extern "C" fn initialize_vector() -> *mut Vec<f32> {
Box::into_raw(Box::new(Vec::<f32>::new()))
}
#[no_mangle]
pub extern "C" fn push_to_vector(ptr: *mut Vec<f32>, x: f32) -> *mut Vec<f32> {
if ptr.is_null() { return ptr; }
let vector_box = unsafe { Box::from_raw(ptr) };
let mut example_vector = *vector_box;
example_vector.push(x);
Box::into_raw(Box::new(example_vector))
}
#[no_mangle]
pub extern "C" fn sum_vector(ptr: *mut Vec<f32>) -> f32 {
if ptr.is_null() { return 0.0; }
let vector_box = unsafe { Box::from_raw(ptr) };
let example_vector = *vector_box;
return example_vector.iter().sum();
}
initialize_vector
创建 aVec
并将其包装在 a 中Box
,将原始指针返回给调用者。调用者现在负责适当地释放分配。
push_to_vector
取得 的所有权Box<Vec<f32>>
,将Vec
移出Box
,释放Box
进程中分配的内存。然后它将一个项目添加到向量中,在 周围创建一个全新的Box
(具有相关分配)Vec
并返回它。
sum_vector
还取得 的所有权Box<Vec<f32>>
,将Vec
移出Box
并释放内存分配。由于 的所有权Vec
不会离开函数,Rust 会Vec
在函数退出时自动释放与 相关的内存。
使用该库的 C# 代码可能如下所示:
using System;
using System.Runtime.InteropServices;
internal class Blabla
{
[DllImport("Example")]
unsafe static public extern IntPtr initialize_vector();
[DllImport("Example")]
unsafe static public extern IntPtr push_to_vector(IntPtr ptr, float x);
[DllImport("Example")]
unsafe static public extern float sum_vector(IntPtr ptr);
static public unsafe void Main()
{
IntPtr vec_ptr = initialize_vector();
vec_ptr = push_to_vector(vec_ptr, (float) 2.2);
vec_ptr = push_to_vector(vec_ptr, (float) 3.3);
float result = sum_vector(vec_ptr);
// is the memory allocated for the vector in Rust freed right now?
Console.WriteLine(string.Format("Result: {0}", result));
Console.ReadLine();
}
}
通常,建议使用SafeHandle
DLL 函数返回的指针来完成,请参见例如this question或this example。我知道 的目的SafeHandle
主要是在某些情况下,当发生意外情况时调用析构函数。
由于在调用函数后没有必要释放 Rust 向量,在给定的情况下sum_vector
是否仍然建议使用SafeHandle
,如果是 - 如何?还是我可以保留代码原样,一切都很好?
解决方案
推荐阅读
- javascript - Nodejs 阻止代码执行,直到它接收到 TCP 命令(挂起一个 GUI 事件)
- python - 如何在 3D 渲染中匹配卡片放置?
- javascript - 我的播放列表插件不适用于 videojs?
- sql - 使用 IN 子句立即执行
- python - python中从十六进制到ASCII
- mysql - sql楼的进出记录
- javascript - 仅当数组长度发生变化时如何执行.js
- javascript - 如果用户未填写输入字段,如何发出咆哮警报?
- amazon-web-services - 从 AWS Lambda 运行脚本时出现 utf 错误,但从手动 ssh 运行时却没有
- javascript - 单击多个 ID 时显示/隐藏文本