P/invoke 函数获取结构体指针
CreateProcess 等函数具有指向结构。在 CI 中,只需将 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);
但如果我尝试为 lpProcessAttributes
参数或 lpThreadAttributes
参数传递 null
,我得到编译器错误:
错误 2 参数 3:无法从“
”转换参考 调试.Wrappers.SECURITY_ATTRIBUTES'
如何修改上述函数签名,以便我可以为 SECURITY_ATTRIBUTES 参数传递 null
而不会出现此编译器错误? (如果我愿意的话,还可以传递一个真实的结构?)
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.
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);
But if I try to pass null
for the lpProcessAttributes
argument or lpThreadAttributes
argument, I get a compiler error:
Error 2 Argument 3: cannot convert from '<null>' to 'ref
Debugging.Wrappers.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?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,我终于(!)找到了一种更好的方法:
将 SECURITY_ATTRIBUTES 声明为类而不是结构,并且不通过引用传递它。 :-)
额外的好处:这还可以让你在 SECURITY_ATTRIBUTES 上声明一个合适的构造函数来初始化 nLength。
OK, I finally(!) found an even better way of doing this:
Declare SECURITY_ATTRIBUTES as class instead of struct and don't pass it by ref. :-)
Bonus: this also lets you declare a decent constructor on SECURITY_ATTRIBUTES which initializes nLength.
null
仅对 .Net 中的引用类型有效。您的 SECURITY_ATTRIBUTES 是一个struct
,它是一个ValueType
。您需要传递一个空的 SECURITY_ATTRIBUTES 结构,而不是传递 null。 (只需在通话中说出new SECURITY_ATTRIBUTES()
)。一种更简洁的方法是向结构中添加静态 Empty 属性,然后仅传递 SECURITY_ATTRIBUTES.Empty ,
或者更好的是,不要使用 P/Invoke 创建 Process,而是查看 System. Diagnostics.Process 类,它可能应该执行您需要的操作。
null
is only valid for Reference types in .Net. your SECURITY_ATTRIBUTES is astruct
, which is aValueType
. Rather than passing null, you need to pass an empty SECURITY_ATTRIBUTES structure. (just saynew SECURITY_ATTRIBUTES()
) in your call.A cleaner method is to add a static Empty property to your struct, and just pass
SECURITY_ATTRIBUTES.Empty
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.