我尝试使用C#创建管道。代码很简单,但是我收到一条错误,说“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。”
这是我表格的完整代码:
public partial class Form1 : Form
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CreatePipe(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, SECURITY_ATTRIBUTES lpPipeAttributes, int nSize);
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public DWORD nLength;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
public Form1()
{
InitializeComponent();
}
private void btCreate_Click(object sender, EventArgs e)
{
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
sa.nLength = (DWORD)System.Runtime.InteropServices.Marshal.SizeOf(sa);
sa.lpSecurityDescriptor = IntPtr.Zero;
sa.bInheritHandle = true;
SafeFileHandle hWrite = null;
SafeFileHandle hRead = null;
if (CreatePipe(out hRead, out hWrite, sa, 4096))
{
MessageBox.Show("Pipe created !");
}
else
MessageBox.Show("Error : Pipe not created !");
}
}
在顶部我声明:使用DWORD = System.UInt32;
非常感谢有人可以提供帮助。
答案 0 :(得分:3)
受保护内存违规的原因是因为CreatePipe的Windows API期望指针值到内存区域,该函数将用作安全属性结构的弹簧板。只需传入SECURITY_ATTRIBUTES结构就会覆盖安全内存(尚未分配给应用程序的页面),从而导致受保护的内存错误。
传入IntPtr来表示此指针,解决了您的问题。
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CreatePipe(ref IntPtr hReadPipe, ref IntPtr hWritePipe, IntPtr lpPipeAttributes, int nSize);
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public DWORD nLength;
public IntPtr lpSecurityDescriptor;
[MarshalAs(UnmanagedType.Bool)]
public bool bInheritHandle;
}
public Form1()
{
InitializeComponent();
}
private void btnCreate_Click(object sender, EventArgs e)
{
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
sa.nLength = (DWORD)System.Runtime.InteropServices.Marshal.SizeOf(sa);
sa.lpSecurityDescriptor = IntPtr.Zero;
sa.bInheritHandle = true;
IntPtr attr = Marshal.AllocHGlobal(Marshal.SizeOf(sa));
Marshal.StructureToPtr(sa, attr, true);
IntPtr hWrite = new IntPtr();
IntPtr hRead = new IntPtr();
if (CreatePipe(ref hRead, ref hWrite, attr, 4096))
{
MessageBox.Show("Pipe created !");
}
else
{
int error = Marshal.GetLastWin32Error();
MessageBox.Show("Error : Pipe not created ! LastError= " + error);
}
}
答案 1 :(得分:2)
只需更改声明,以便SECURITY_ATTRIBUTES
为指针:
public static extern bool CreatePipe(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, ref SECURITY_ATTRIBUTES lpPipeAttributes, int nSize);