Bob*_*Bob 5 c# pinvoke struct marshalling
我想打电话给LsaOpenPolicy,它需要一个LSA_OBJECT_ATTRIBUTES结构。我正在使用来自pinvoke.net的结构定义。该结构具有领域public LSA_UNICODE_STRING ObjectName;。
该LSA_OBJECT_ATTRIBUTESMSDN文章说:
当您调用时
LsaOpenPolicy,将此函数的成员初始化为NULL或零,因为该函数不使用该信息。
特别是:
对象名
应该为NULL。
虽然我可以将LSA_OBJECT_ATTRIBUTESstruct 的其他字段分配给IntPtr.Zero(或仅将其分配给0值类型),但看不到的方法ObjectName。特别,
无法将类型'System.IntPtr'隐式转换为'LSA_UNICODE_STRING'
在这种情况下我该怎么办?我应该初始化LSA_UNICODE_STRING长度为零(长度0,最大长度0,空/空缓冲区)的a吗?我应该更改LSA_OBJECT_ATTRIBUTES定义以便该字段为IntPtr吗?我应该使它为可空值并分配null给该字段吗?
我对内存管理的经验很少,因此对于可能导致内存泄漏的任何事情我都非常警惕。
声明LSA_UNICODE_STRING为 aclass而不是 a 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;
}
Run Code Online (Sandbox Code Playgroud)
您可以采用相同的策略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
);
Run Code Online (Sandbox Code Playgroud)
请注意,pinvoke.netSetLastError=true上的声明错误地使用了on LsaOpenPolicy。这是错误的,因为错误代码在返回值中返回。我还删除了PreserveSigto的设置,true因为这是默认设置。他们的声明LSA_OBJECT_ATTRIBUTES也似乎是错误的,因为ObjectName参数的类型LSA_UNICODE_STRING是结构而不是指向它的指针。
我建议您以极度怀疑的态度对待您在 pinvoke.net 上找到的内容。该网站上的大部分声明都是错误的。
您询问使用可为空类型的可能性。根据@JaredPar 的回答,这不是一个选项。
| 归档时间: |
|
| 查看次数: |
1382 次 |
| 最近记录: |