6

我想打电话LsaOpenPolicy,它需要一个LSA_OBJECT_ATTRIBUTES结构。我正在使用pinvoke.net 的结构定义。这个结构有字段public LSA_UNICODE_STRING ObjectName;

LSA_OBJECT_ATTRIBUTESMSDN 文章说:

当您调用LsaOpenPolicy时,将此结构的成员初始化为NULL或零,因为该函数不使用该信息。

特别是:

对象名

    应该是NULL

虽然我可以将LSA_OBJECT_ATTRIBUTES结构的其他字段分配给IntPtr.Zero(或者只是简单地分配给0值类型),但我看不到为ObjectName. 具体来说,

无法将类型“System.IntPtr”隐式转换为“LSA_UNICODE_STRING”

在这种情况下我该怎么办?我应该初始化一个LSA_UNICODE_STRING长度为零的(长度为0,最大长度为0,空/空缓冲区)吗?我应该更改LSA_OBJECT_ATTRIBUTES定义以使该字段为IntPtr? 我应该让它为空并分配null给那个字段吗?

我对内存管理的经验很少,所以我对任何可能导致内存泄漏的事情都很警惕。

4

1 回答 1

5

声明LSA_UNICODE_STRING为 aclass而不是 a struct。通过这样做,您可以使其成为引用类型。LSA_OBJECT_ATTRIBUTES这与因为ObjectNamehas type的声明相匹配,该类型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=trueon LsaOpenPolicy。这是错误的,因为错误代码会在返回值中返回。我还删除了 to 的设置,PreserveSig因为true这是默认设置。他们的声明LSA_OBJECT_ATTRIBUTES也出现了错误,因为ObjectName参数的类型LSA_UNICODE_STRING是结构而不是指向它的指针。

我建议您以极端怀疑的态度对待您在 pinvoke.net 上发现的内容。该网站上的大部分声明都是不正确的。

您询问使用可为空类型的可能性。根据@JaredPar's answer here,这不是一个选择。

于 2013-06-04T10:47:00.507 回答