P/invoke函数采用指向结构的指针 [英] P/invoke function taking pointer to struct

查看:90
本文介绍了P/invoke函数采用指向结构的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

诸如 CreateProcess 的功能具有签名以指向结构的指针.在C语言中,我只是将NULL用作可选参数的指针,而不是在堆栈上创建虚拟struct对象并将指针传递给虚拟对象.

Functions such as CreateProcess have signatures taking pointers to structs. In C I would just pass NULL as a pointer for the optional parameters, instead of creating a dummy struct object on the stack and passing a pointer to the dummy.

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

In C#, I have declared it as (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);

但是,如果我尝试为lpProcessAttributes参数或lpThreadAttributes参数传递null,则会出现编译器错误:

But if I try to pass null for the lpProcessAttributes argument or lpThreadAttributes argument, I get a compiler error:

错误2参数3:无法从'< null>'转换引用 Debugging.Wrappers.SECURITY_ATTRIBUTES'

Error 2 Argument 3: cannot convert from '<null>' to 'ref Debugging.Wrappers.SECURITY_ATTRIBUTES'

如何修改上面的函数签名,以便仅将null传递给SECURITY_ATTRIBUTES参数,而不会出现此编译器错误? (如果我愿意,还可以传递真实的结构吗?)

How can I modify the above function signature so that I can just pass null for the SECURITY_ATTRIBUTES arguments, without this compiler error? (And also be able to pass a real struct if I want to?)

推荐答案

null仅对.Net中的引用类型有效.您的SECURITY_ATTRIBUTES是struct,这是ValueType.您需要传递一个空的SECURITY_ATTRIBUTES结构,而不是传递null. (只需说出new SECURITY_ATTRIBUTES()).

null is only valid for Reference types in .Net. your SECURITY_ATTRIBUTES is a struct, which is a ValueType. Rather than passing null, you need to pass an empty SECURITY_ATTRIBUTES structure. (just say new SECURITY_ATTRIBUTES()) in your call.

一种更清洁的方法是将静态的Empty属性添加到您的结构中,然后传递SECURITY_ATTRIBUTES.Empty

A cleaner method is to add a static Empty property to your struct, and just pass 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类,该类应该可以完成您需要的操作.

Or better yet, rather than using P/Invoke to create a Process, check out the System.Diagnostics.Process class, which should probably do what you need it to.

这篇关于P/invoke函数采用指向结构的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆