我有一个应用程序,似乎只有在程序关闭后才会抛出异常.这是非常不一致的.(我们都知道不一致的bug有多么有趣......)
我的猜测是在清理过程中出现错误.但是这些内存读/写错误似乎表明我的"不安全"代码使用(指针?)有问题.
我感兴趣的是调试这些情况的最佳方法是什么?
你如何调试已经关闭的程序?
我正在寻找一个解决更大问题的起点.
这些错误似乎以多种方式呈现(一些运行时,一些调试):
1: .NET-BroadcastEventWindow.2.0.0.0.378734a.0: Application.exe - Application Error
The instruction at "0x03b4eddb" referenced memory at "0x00000004". The memory could not be "written". 2: Application.vshost.exe - Application Error
The instruction at "0x0450eddb" referenced memory at "0x00000004". The memory could not be "written". 3: Application.vshost.exe - Application Error
The instruction at "0x7c911669" referenced memory at "0x00000000". The memory could not be "read". 4: Application.vshost.exe - Application Error
The instruction at "0x7c910ed4" referenced memory at "0xfffffff8". The memory could …
我有一个非托管DLL,其函数将指针作为参数.如何从C#传递指针而不是"不安全"?
这是一些示例代码:
[DllImport(@"Bird.dll")]
private static extern bool foo(ushort *comport);
Run Code Online (Sandbox Code Playgroud)
标题中的相应条目:
BOOL DLLEXPORT foo(WORD *pwComport);
Run Code Online (Sandbox Code Playgroud)
当我尝试简单地取消引用它(&comport)时,我得到一个错误说:" 指针和固定大小的缓冲区只能在不安全的上下文中使用. "
我该如何解决这个问题?
我正在创建一个实现图像处理的性能关键型应用程序.我正在使用一些像素指针使用我的结构命名Pixel来做一些处理.我有很多代码部分迭代整个位图数据,为了代码的可重用性和模块性,我正在设计一个方法,它将采取一个动作并将其应用于图像的所有像素(如地图)功能).但是,当我写Action<Pixel*>Visual Studio抱怨代码时,该类型Pixel*可能不会被用作类型参数.整个类都在unsafe上下文中,我Pixel到处都在使用指针,但我不能将像素指针用作Action的模板类.
我可以使用,Action<IntPtr>但我需要在每次迭代中将它转换为方法体内的适当指针,这将杀死"性能关键"的整个想法.
长话短说,我将提供一个简单的例子,它可能有用:
public struct Vector3f {
public float x;
public float y;
public float z;
public unsafe float this[int index] {
get {
// Get "p" somehow, so that it points to "this"...
return p[index];
}
set {
// Get "p" somehow, so that it points to "this"...
p[index] = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我猜你有我的观点:
var v = new Vector3f();
Assert(v.x == v[0]);
Run Code Online (Sandbox Code Playgroud)
编辑1:
对于那些仍然问:)
Assert(v.y == v[1]);
Assert(v.z == v[2]);
Run Code Online (Sandbox Code Playgroud)
编辑2:
这会fixed产生多余的开销吗?或者这个结构可能已经修复,因此fixed在这里没有效果,只需要满足编译器的需要?可能的答案.
以下代码反映在.Net Framework中:
[SecurityCritical]
public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val){
try{
byte* numPtr = (byte*) (((void*) ptr) + ofs);
if ((((int) numPtr) & 7) == 0){
*((long*) numPtr) = val;
}
else{
byte* numPtr2 = (byte*) &val;
numPtr[0] = numPtr2[0];
numPtr[1] = numPtr2[1];
numPtr[2] = numPtr2[2];
numPtr[3] = numPtr2[3];
numPtr[4] = numPtr2[4];
numPtr[6] = numPtr2[6];
numPtr[7] = numPtr2[7];
}
}
catch (NullReferenceException){
throw new AccessViolationException();
}
}
Run Code Online (Sandbox Code Playgroud)
在我看来,*((long*) numPtr) = val足够,而且效率很高.
为什么这么复杂?
我可以以某种方式获得一个数组std::ptr::read吗?
我想做一些接近的事情:
let mut v: Vec<u8> = ...
let view = &some_struct as *const _ as *const u8;
v.write(&std::ptr::read<[u8, ..30]>(view));
Run Code Online (Sandbox Code Playgroud)
哪个在此表单中无效(不能使用数组签名).
只是搞乱c#的不安全方面
unsafe {
char* m = stackalloc char[3+1];
m[0] = 'A';
m[1] = 'B';
m[2] = 'C';
m[3] = '\0';
for (char* c = m; *c != '\0'; c++) {
Console.WriteLine(*c);
}
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
是否可以像C中一样string为char指针指定文字,或者我必须像上面的代码片段那样进行操作?
我有一个[u8; 16384]和一个u16.我如何"暂时转换"数组,以便我可以同时设置两个u8s,第一个到最低有效字节,第二个到最高有效字节?
我正在尝试编写一个缓冲区用于解析,所以我可以在解析它们时从前面拉出记录,理想情况下不会制作任何副本,只是在运行时将缓冲区前面的块的所有权转移掉.这是我的实现:
struct BufferThing {
buf: Vec<u8>,
}
impl BufferThing {
fn extract(&mut self, size: usize) -> Vec<u8> {
assert!(size <= self.buf.len());
let remaining: usize = self.buf.len() - size;
let ptr: *mut u8 = self.buf.as_mut_ptr();
unsafe {
self.buf = Vec::from_raw_parts(ptr.offset(size as isize), remaining, remaining);
Vec::from_raw_parts(ptr, size, size)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这会编译,但signal: 11, SIGSEGV: invalid memory reference在开始运行时会发生恐慌.这与Nomicon中的示例大致相同,但我试图在它上面做Vec,我试图分割一个字段而不是对象本身.
是否可以在不复制其中一个的情况下执行此操作Vec?Nomicon或其他文档中是否有一些部分可以解释为什么我要把所有内容都搞砸了unsafe?
在不安全的代码中,只要它们不用于写入相同的索引,对同一个数组有几个可变引用(而不是指针)是否正确?
我想产生几个(不同的)底层数组的可变视图,我可以从不同的线程修改.
如果不相交的部分是连续的,那么通过调用split_at_mut切片这是微不足道的:
let mut v = [1, 2, 3, 4];
{
let (left, right) = v.split_at_mut(2);
left[0] = 5;
right[0] = 6;
}
assert!(v == [5, 2, 6, 4]);
Run Code Online (Sandbox Code Playgroud)
但我也希望揭露不连续的不相交部分.为简单起见,假设我们想为偶数索引检索可变"视图",为奇数索引检索另一个可变"视图".
相反split_at_mut(),我们无法检索两个可变引用(我们想要一个安全的抽象!),所以我们使用两个结构实例,只暴露偶数(相应的奇数)索引的可变访问:
let data = &mut [0i32; 11];
let (mut even, mut odd) = split_fields(data);
// …
Run Code Online (Sandbox Code Playgroud)
使用一些不安全的代码,很容易获得这样一个安全的抽象.这是一个可能的实现:
use std::marker::PhantomData;
struct SliceField<'a> {
ptr: *mut i32,
len: usize,
field: usize,
marker: PhantomData<&'a mut i32>,
}
impl SliceField<'_> {
fn …Run Code Online (Sandbox Code Playgroud)