我正在尝试以一种传递标志的方式来PInvoke CreateDesktop,以便由子进程继承桌面。声明如下:
[DllImport("user32", EntryPoint = "CreateDesktopW", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags,
int dwDesiredAccess, [MarshalAs(UnmanagedType.LPStruct)] SECURITY_ATTRIBUTES lpsa);
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}我的用法如下:
Win32.SECURITY_ATTRIBUTES sa = new Win32.SECURITY_ATTRIBUTES();
sa.nLength = Marshal.SizeOf(sa);
sa.bInheritHandle = 1;
testDesktopHandle = Win32.CreateDesktop(name, IntPtr.Zero, IntPtr.Zero, 0, Win32.GENERIC_ALL, sa);不幸的是,它不能工作,我得到了以下错误:
System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'parameter #6': Invalid managed/unmanaged type combination (this value type must be paired with Struct).你知道我做错了什么吗?
发布于 2009-09-16 17:35:21
尝试将参数#6更改为
static extern IntPtr CreateDesktop(..., [In] ref SECURITY_ATTRIBUTES lpsa);(这将进行编译,并且不会在运行时抛出异常,但我仅使用伪参数对其进行了测试。)
与CreateDesktop的C++声明进行比较
HDESK WINAPI CreateDesktop(..., __in_opt LPSECURITY_ATTRIBUTES lpsa);
↑ ↑ ↑
[In] ref SECURITY_ATTRIBUTES lpsaLP代表“长指针”,即LPSECURITY_ATTRIBUTES是指向SECURITY_ATTRIBUTES结构的指针。因此,在C#中,您需要通过引用传递结构实例(值类型)。
发布于 2009-09-16 17:35:54
请考虑使用以下原型:
[DllImport("user32", EntryPoint = "CreateDesktopW", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags,
int dwDesiredAccess, IntPtr lpsa);然后,要调用它,只需创建一个固定的句柄:
GCHandle handle = GCHandle.Alloc(myStruct);
try {
IntPtr pinnedAddress = handle.AddrOfPinnedObject();
}
finally {
handle.Free();
}这对于使用结构调用PInvoke的方法非常有效。
https://stackoverflow.com/questions/1434363
复制相似问题