C# 调用对象时是否建议使用安全句柄';s方法也会破坏对象吗?

C# 调用对象时是否建议使用安全句柄';s方法也会破坏对象吗?,c#,rust,pinvoke,ffi,C#,Rust,Pinvoke,Ffi,Rust库提供三个功能: 浮点向量的构造函数 将数字推送到向量的函数 在向量上求和的函数 像这样: #[无损坏] pub extern“C”fn initialize_vector()->*mut Vec{ Box::into_raw(Box::new(Vec:::new()) } #[没有损坏] pub extern“C”fn推送向量(ptr:*mut-Vec,x:f32)->*mut-Vec{ 如果ptr.is_null(){return ptr;} 设vector_box=unsafe

Rust库提供三个功能:

  • 浮点向量的构造函数
  • 将数字推送到向量的函数
  • 在向量上求和的函数
像这样:

#[无损坏]
pub extern“C”fn initialize_vector()->*mut Vec{
Box::into_raw(Box::new(Vec:::new())
}
#[没有损坏]
pub extern“C”fn推送向量(ptr:*mut-Vec,x:f32)->*mut-Vec{
如果ptr.is_null(){return ptr;}
设vector_box=unsafe{box::from_raw(ptr)};
让mut示例_vector=*vector_box;
示例_矢量推(x);
Box::into_raw(Box::new(示例_vector))
}
#[没有损坏]
发布外部“C”fn和向量(ptr:*mut Vec)->f32{
如果ptr.is_null(){返回0.0;}
设vector_box=unsafe{box::from_raw(ptr)};
例如_vector=*vector_框;
返回示例_vector.iter().sum();
}
initialize_vector
创建一个
Vec
并将其包装在
框中,将原始指针返回给调用方。调用者现在负责适当地释放分配

push_to_vector
拥有
Box
的所有权,在此过程中释放由
Box
分配的内存。然后,它将一个项目添加到向量中,在
向量
周围创建一个全新的
(带相关分配),并返回它

sum_vector
还拥有
框的所有权,将
Vec
移出
框,并释放内存分配。由于
Vec
的所有权不会离开该功能,因此当该功能退出时,Rust将自动释放与
Vec
相关的内存

使用该库的C#代码可能如下所示:

使用系统;
使用System.Runtime.InteropServices;
内部类Blabla
{
[DllImport(“示例”)]
不安全的静态公共外部IntPtr initialize_vector();
[DllImport(“示例”)]
不安全的静态公共外部IntPtr push_to_向量(IntPtr ptr,float x);
[DllImport(“示例”)]
不安全的静态公共外部浮点和向量(IntPtr ptr);
静态公共不安全void Main()
{
IntPtr vec_ptr=初始化_vector();
vec_ptr=推送至向量(vec_ptr,(float)2.2);
vec_ptr=推送至向量(vec_ptr,(float)3.3);
浮点结果=和向量(向量ptr);
//为Rust中的向量分配的内存现在是否已释放?
WriteLine(string.Format(“Result:{0}”,Result));
Console.ReadLine();
}
}
通常,建议使用
SafeHandle
完成DLL函数返回的指针,例如,请参阅或。我知道,
SafeHandle
的目的主要是在某些情况下,当意外事件发生时调用析构函数


由于调用
sum_vector
函数后无需释放锈迹向量,因此在给定情况下是否仍建议使用
SafeHandle
,如果是-如何?或者我可以让代码保持原样,一切正常吗?

您的问题是合理的,但我认为提供的代码示例没有意义。在
push_to_vector
sum_vector
中,没有理由拥有
框的所有权。如果您只是简单地更改这些函数以借用数据并还原析构函数,那么代码的性能会更高(减少不必要的(取消)分配)并且更简单。这只是创建MCVE的人工制品吗?@Shepmaster谢谢你的提示!这个例子与我实际做的非常相似,只是它不是浮点而是结构,而且模拟的
sum\u vector
做了一些繁重的计算。因此,分配/解除分配的性能并不重要。但我仍然可以应用您建议的更改(即,仅借用向量并最终使用析构函数)为了用
SafeHandle
类管理C#中的指针。@Shepmaster,我怎么能在没有所有权的情况下推送到向量?
Vec::push
只需要一个
&mut Self
,而
iter
只需要一个
&Self
。分配/解除分配的性能并不重要-我不同意,但只有基准测试才能确定。我的直觉告诉我,为你推送的每一个项目去分配和重新分配内存是非常浪费的。