我今天晚上发现,我写的一些帮助代码是由于将64位指针转换为32位而在64位计算机上发生相当令人讨厌的SIGSERV
崩溃的罪魁祸首。
class FastPixelEditor {
Bitmap m_bitmap;
Rectangle m_source;
BitmapData m_bitmapData;
int m_nativePixelPointer;
public FastPixelEditor(Bitmap bitmap, Rectangle source) {
m_bitmap = bitmap;
m_source = source;
m_bitmapData = m_bitmap.LockBits(source,
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
m_nativePixelPointer = m_bitmapData.Scan0.ToInt32();
}
public void SetPixel(int x, int y, Color color) {
int idx = (y - m_source.Top) * m_source.Width +
(x - m_source.Left);
idx *= 4;
Marshal.WriteInt32((IntPtr)(m_nativePixelPointer + idx),
color.ToArgb());
}
public Color GetPixel(int x, int y) {
int idx = (y - m_source.Top) * m_source.Width +
(x - m_source.Left);
idx *= 4;
return Color.FromArgb(Marshal.ReadInt32((IntPtr)(
m_nativePixelPointer + idx)));
}
public void Unlock() { m_bitmap.UnlockBits(m_bitmapData); }
}
崩溃发生在GetPixel
函数的这一行:
Marshal.ReadInt32((IntPtr)(m_nativePixelPointer + idx))
作为帮助代码,我怀疑强迫任何使用此代码的人在他们的项目上设置/unsafe
编译标志是谨慎的,但使用IntPtr.ToInt64()
似乎真的是hackish(虽然它可能有效)。
IntPtr.Add
似乎正是我所追求的,但此代码必须以.NET 2.0为目标,并且在.NET 4.0中添加了IntPtr.Add
。
我是否被迫在/unsafe
或IntPtr.ToInt64()
之间作出决定,还是有其他选择?
答案 0 :(得分:3)
注意到Marshall.ReadInt32
和Marshall.WriteInt32
实际上有重载,允许指定偏移量:
Marshall.ReadInt32(IntPtr ptr, int ofs)
它们在.NET 2.0中可用。
答案 1 :(得分:2)
IntPtr.Add
的定义如下:
return ptr + offset;
operator+
的{{1}}重载定义如下:
IntPtr
所以..它基本上按照你的建议行事......它只是把它包装在一个更好的函数调用中。你也可以这样做。