如何整理结构数组
本文关键字:数组 结构 何整理 | 更新日期: 2023-09-27 17:59:20
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
const int SystemPowerInformation = 11;
const uint STATUS_SUCCESS = 0;
[StructLayout(LayoutKind.Sequential)]
struct PROCESSOR_POWER_INFORMATION
{
public uint Number;
public uint MaxMhz;
public uint CurrentMhz;
public uint MhzLimit;
public uint MaxIdleState;
public uint CurrentIdleState;
}
[DllImport("powrprof.dll")]
static extern uint CallNtPowerInformation(
int InformationLevel,
IntPtr lpInputBuffer,
int nInputBufferSize,
[MarshalAs(UnmanagedType.LPArray)]
out byte[] lpOutputBuffer,
int nOutputBufferSize
);
static void Main(string[] args)
{
byte[] buffer = new byte[4 * Marshal.SizeOf(typeof(PROCESSOR_POWER_INFORMATION))];
uint retval = CallNtPowerInformation(
SystemPowerInformation,
IntPtr.Zero,
0,
out buffer,
4 * Marshal.SizeOf(typeof(PROCESSOR_POWER_INFORMATION))
);
if (retval == STATUS_SUCCESS)
Console.WriteLine(buffer);
}
}
}
我正试图从CallNtPowerInformation
中获取一些数据。我试图创建一个结构,调用CallNtPowerInformation
并封送其中的数据,但没有成功。因此,我试图看看是否可以将数据放入字节数组,但我得到了以下结果:
对象引用未设置为对象的实例。
我相信我正在将内存分配给缓冲区。
我不知道为什么。任何指示都会有所帮助。
名为SystemPowerInformation
、值为11
的常量名称错误。它应该命名为ProcessorInformation
。
您应该这样声明p/invoke:
[DllImport("powrprof.dll")]
static extern uint CallNtPowerInformation(
int InformationLevel,
IntPtr lpInputBuffer,
int nInputBufferSize,
[Out] PROCESSOR_POWER_INFORMATION[] processorPowerInformation,
int nOutputBufferSize
);
为了调用函数,您需要分配一个大小合适的PROCESSOR_POWER_INFORMATION
结构数组。像这样:
PROCESSOR_POWER_INFORMATION[] powerInfo =
new PROCESSOR_POWER_INFORMATION[procCount];
CallNtPowerInformation
的文档告诉您使用GetSystemInfo
来计算您有多少处理器。您可以使用Environment.ProcessorCount
。
然后你调用这样的函数:
uint retval = CallNtPowerInformation(
ProcessorInformation,
IntPtr.Zero,
0,
powerInfo,
powerInfo.Length*Marshal.SizeOf(typeof(PROCESSOR_POWER_INFORMATION))
);
这里有一个完整的程序:
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
const int ProcessorInformation = 11;
const uint STATUS_SUCCESS = 0;
[StructLayout(LayoutKind.Sequential)]
struct PROCESSOR_POWER_INFORMATION
{
public uint Number;
public uint MaxMhz;
public uint CurrentMhz;
public uint MhzLimit;
public uint MaxIdleState;
public uint CurrentIdleState;
}
[DllImport("powrprof.dll")]
static extern uint CallNtPowerInformation(
int InformationLevel,
IntPtr lpInputBuffer,
int nInputBufferSize,
[Out] PROCESSOR_POWER_INFORMATION[] lpOutputBuffer,
int nOutputBufferSize
);
static void Main(string[] args)
{
int procCount = Environment.ProcessorCount;
PROCESSOR_POWER_INFORMATION[] procInfo =
new PROCESSOR_POWER_INFORMATION[procCount];
uint retval = CallNtPowerInformation(
ProcessorInformation,
IntPtr.Zero,
0,
procInfo,
procInfo.Length * Marshal.SizeOf(typeof(PROCESSOR_POWER_INFORMATION))
);
if (retval == STATUS_SUCCESS)
{
foreach (var item in procInfo)
{
Console.WriteLine(item.CurrentMhz);
}
}
}
}
}
将您的ummanaged调用的参数类型更改为IntPtr:
[DllImport("powrprof.dll")]
static extern uint CallNtPowerInformation(
int InformationLevel,
IntPtr lpInputBuffer,
int nInputBufferSize,
IntPtr lpOutputBuffer,
int nOutputBufferSize
);
在调用它之前使用这个:
GCHandle handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
IntPtr ptr = handle.AddrOfPinnedObject();
然后调用它,将该IntPtr作为参数进行传递。
使用后不要忘记释放!