使用 PInvoke 时,何时应使用 class 以及何时应在要求输入指向 NAME 结构的指针时使用 struct?

When using PInvoke, when should you use class and when struct when asked to input a pointer to a NAME struct?

抱歉,如果问题有点离题。在 C# 中使用 PInvoke 时,某些函数需要将填充数据的结构,但据我所知,某些函数仅在所述结构在 C# 中写为 class 时才起作用,因此而不是 public struct StructName 你会做 public class StructName.

如果你不明白我的意思,你可以尝试运行这段代码,看看会发生什么

using System.Runtime.InteropServices;

[DllImport("kernel32.dll")]
public static extern void GetSystemInfo([In, Out] SystemInfoStruct lpSystemInfo);

[DllImport("kernel32.dll")]
public static extern void GetSystemInfo([In, Out] SystemInfoClass lpSystemInfo);

[StructLayout(LayoutKind.Sequential)]
public struct SystemInfoStruct
{
    public ushort wProcessorArchitecture;
    private ushort wReserved;
    public uint dwPageSize;
    public IntPtr lpMinimumApplicationAddress;
    public IntPtr lpMaximumApplicationAddress;
    public IntPtr dwActiveProcessorMask;
    public uint dwNumberOfProcessors;
    private uint dwProcessorType;
    public uint dwAllocationGranularity;
    public ushort wProcessorLevel;
    public ushort wProcessorRevision;
}

[StructLayout(LayoutKind.Sequential)]
public class SystemInfoClass
{
    public ushort wProcessorArchitecture;
    private ushort wReserved;
    public uint dwPageSize;
    public IntPtr lpMinimumApplicationAddress;
    public IntPtr lpMaximumApplicationAddress;
    public IntPtr dwActiveProcessorMask;
    public uint dwNumberOfProcessors;
    private uint dwProcessorType;
    public uint dwAllocationGranularity;
    public ushort wProcessorLevel;
    public ushort wProcessorRevision;
}

class Program
{
    static void Main()
    {
        //SystemInfoClass infoClass = new SystemInfoClass();
        //GetSystemInfo(infoClass);

        //SystemInfoStruct infoStruct = new SystemInfoStruct();
        //GetSystemInfo(infoStruct);
    }
}

至少对我来说,使用结构失败并返回 r/w 拒绝访问错误,另一方面,使用 class 有效。 所以,问题是,什么时候应该使用结构,什么时候应该对 PInvoke 函数使用 classes,还是应该始终使用 classes? 谁知道,也许我忽略了一些重要的事情。

一般来说,您应该使用 https://pinvoke.net/ 告诉您应该使用的任何内容。如果它说需要用 struct 调用它,则传递 struct。如果它说需要用 class 调用它,则传递 class.

现在,如果你想过危险的生活,你可以尝试互换 classstruct,但要注意传递 class 并不完全等同通过 struct;相反,它相当于通过 ref.

传递 struct