我想调用LsaOpenPolicy
,它采用LSA_OBJECT_ATTRIBUTES
结构。我正在使用the struct definition from pinvoke.net。此结构具有字段public LSA_UNICODE_STRING ObjectName;
。
LSA_OBJECT_ATTRIBUTES
MSDN文章说:
当您致电
LsaOpenPolicy
时,请将此结构的成员初始化为 NULL 或零,因为该功能不使用该信息。
具体而言:
的ObjectName
应该是 NULL 。
虽然我可以将LSA_OBJECT_ATTRIBUTES
结构体的其他字段分配给IntPtr.Zero
(或仅仅为0
指定值类型),但我无法看到ObjectName
结构的其他字段1}}。具体地,
无法将类型'System.IntPtr'隐式转换为'LSA_UNICODE_STRING'
在这种情况下我该怎么办?我应该只初始化长度为零的LSA_UNICODE_STRING
(长度为0,最大长度为0,空/空缓冲区)?我应该更改LSA_OBJECT_ATTRIBUTES
定义,以便该字段是IntPtr
吗?我应该让它可以为空并将null
分配给该字段吗?
我对内存管理的经验很少,所以我对任何可能导致内存泄漏的事情都很谨慎。
答案 0 :(得分:3)
将LSA_UNICODE_STRING
声明为class
而不是struct
。通过这样做,您可以将其作为引用类型。这符合LSA_OBJECT_ATTRIBUTES
的声明,因为ObjectName
具有类型PLSA_UNICODE_STRING
,它是指向结构的指针。执行此操作时,您需要指定LayoutKind.Sequential
,因为这不是类的默认值。完成此更改后,您可以将变量设置为null
。
[StructLayout(LayoutKind.Sequential)]
class PLSA_UNICODE_STRING
{
public UInt16 Length;
public UInt16 MaximumLength;
public IntPtr Buffer;
}
您可以对LSA_OBJECT_ATTRIBUTES
采用相同的政策,以便将其作为null
传递。
[StructLayout(LayoutKind.Sequential)]
class PLSA_OBJECT_ATTRIBUTES
{
public uint Length;
public IntPtr RootDirectory;
public PLSA_UNICODE_STRING ObjectName;
public uint Attributes;
public IntPtr SecurityDescriptor;
public IntPtr SecurityQualityOfService;
}
[DllImport("advapi32.dll")]
static extern uint LsaOpenPolicy(
PLSA_UNICODE_STRING SystemName,
PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
uint DesiredAccess,
out IntPtr PolicyHandle
);
请注意,pinvoke.net上的声明错误地使用了SetLastError=true
上的LsaOpenPolicy
。这是错误的,因为错误代码返回到返回值。我还删除了PreserveSig
到true
的设置,因为这是默认设置。它们的LSA_OBJECT_ATTRIBUTES
声明也显示错误,因为ObjectName
参数的类型LSA_UNICODE_STRING
是结构而不是指向它的指针。
我建议你对pinvoke.net上发现的内容持极端怀疑态度。该网站上的很大一部分声明都是不正确的。
您询问使用可空类型的可能性。根据@ JaredPar的answer here,这不是一个选择。