代码之家  ›  专栏  ›  技术社区  ›  Tim Lovell-Smith

P/invoke函数获取指向结构[duplicate]的指针

  •  6
  • Tim Lovell-Smith  · 技术社区  · 14 年前

    功能,如 CreateProcess 让签名指向结构。在C中,我只想通过 NULL

    在C#中,我将其声明为(p/invoke)

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            public static extern bool CreateProcess(
                string lpApplicationName,
                string lpCommandLine,
                ref SECURITY_ATTRIBUTES lpProcessAttributes,
                ref SECURITY_ATTRIBUTES lpThreadAttributes,
                bool bInheritHandles,
                CreateProcessFlags dwProcessCreationFlags,
                IntPtr lpEnvironment,
                string lpCurrentDirectory,
                ref STARTUPINFO lpStartupInfo,
                ref PROCESS_INFORMATION lpProcessInformation);
    

    null 对于 lpProcessAttributes lpThreadAttributes

    调试.Wrappers.SECURITY\u属性

    如何修改上面的函数签名以便我可以通过

    2 回复  |  直到 6 年前
        1
  •  3
  •   Mark H    14 年前

    null 仅对.Net中的引用类型有效。你的安全属性是 struct ,这是一个 ValueType . 您需要传递一个空的安全属性结构,而不是传递null(就说吧 new SECURITY_ATTRIBUTES()

    一个更干净的方法是向结构中添加一个静态空属性,然后只传递 SECURITY_ATTRIBUTES.Empty

    [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_ATTRIBUTES {
        public int nLength;
        public IntPtr lpSecurityDescriptor;
        public int bInheritHandle;
    
        public static SECURITY_ATTRIBUTES Empty {
            get {
                return new SECURITY_ATTRIBUTES {
                    nLength = sizeof(int)*2 + IntPtr.Size,
                    lpSecurityDescriptor = IntPtr.Zero,
                    bInheritHandle = 0,
                };
            }
        }
    }
    

    或者更好的方法是,与其使用P/Invoke来创建流程,不如检查 System.Diagnostics.Process

        2
  •  6
  •   Tim Lovell-Smith    14 年前

    好吧,我终于(!)找到了更好的方法:

    将SECURITY\u属性声明为class而不是struct,并且不要通过ref传递它:-)

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool CreateProcess(
            string lpApplicationName,
            StringBuilder lpCommandLine,
            SECURITY_ATTRIBUTES lpProcessAttributes,
            SECURITY_ATTRIBUTES lpThreadAttributes,
            bool bInheritHandles,
            CreateProcessFlags dwCreationFlags,
            IntPtr lpEnvironment,
            string lpCurrentDirectory,
            STARTUPINFO lpStartupInfo, /// Required
            PROCESS_INFORMATION lpProcessInformation //Returns information about the created process
            );
    
    /// <summary>
    /// See http://msdn.microsoft.com/en-us/library/aa379560(v=VS.85).aspx
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public class SECURITY_ATTRIBUTES
    {
        public uint nLength;
        public IntPtr lpSecurityDescriptor;
        [MarshalAs(UnmanagedType.Bool)] public bool bInheritHandle;
    }
    

    好处:这还允许您在初始化nLength的SECURITY\u属性上声明一个像样的构造函数。