使用Python ctypes与nvapi接口(附示例代码)
这是我之前问题的后续:关于python ctypes和nvapi的帮助
我发这个新问题是因为我在之前的问题中已经选择了一个答案,而现在问题的方向发生了变化。
我想用python来查询nvapi.dll,以获取我的显卡使用率。
这是在C#中实现的方法(下面有链接):http://code.google.com/p/open-hardware-monitor/source/browse/trunk/Hardware/Nvidia/NVAPI.cs
因为我只需要其中一小部分功能,所以我不想换成其他语言。我觉得ctypes应该能做到这一点……但我就是搞不清楚怎么做。我之前从来没有用过Python的ctypes。
为了查询显卡使用率,我首先需要调用NvAPI_Initialize函数。同时还需要使用查询接口来引用这个函数:
from ctypes import *
nvapi = WinDLL("nvapi.dll")
nvapi_QueryInterface = nvapi.nvapi_QueryInterface
使用上面的代码,我可以访问nvapi_QueryInterface,但我不知道怎么复制这一部分:
private static void GetDelegate<T>(uint id, out T newDelegate)
where T : class
{
IntPtr ptr = nvapi_QueryInterface(id);
if (ptr != IntPtr.Zero)
{
newDelegate =
Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
}
else
{
newDelegate = null;
}
}
来引用初始化和使用函数:
GetDelegate(0x0150E828, out NvAPI_Initialize);
GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages);
我对这个的理解可能还是不太对,但我花了不少时间在这上面,希望有人能帮我指明正确的方向,因为我有点迷茫,不知道该怎么继续。
有人能帮我理解如何让这小部分代码直接在python中工作吗?我最终只需要能够调用NvAPI_GPU_GetUsages函数。
谢谢。
1 个回答
为了查询GPU的使用情况,我首先需要调用NvAPI_Initialize这个函数。
其实,这里涉及到两个初始化函数:一个来自静态库nvapi.lib,它会尝试动态加载nvapi.dll,找到一些函数,然后调用动态链接库中的第二个初始化函数。调用NvApi_Initialize时的步骤大致如下:
检查nvapi.dll是否已经加载,如果没有,就加载它。
使用GetProcAddress获取nvapi_QueryInterface这个函数的指针。然后用这个新获得的函数来查询ID为0x150E828的接口。这就是动态库中的第二个初始化函数。
调用获得的初始化函数。如果这个函数成功了(返回值为0表示成功),就通过nvapi_QueryInterface获取两个新的函数指针,使用的ID是0x33C7358C(我们称之为ENTER)和0x593E8644(EXIT)。
所以,如果你想保持纯Python,你基本上需要用ctypes来复现这些步骤,这其实很简单。完成后,nvapi.dll中有一个清理函数,你可以用ID0xD22BDD7E来查询这个函数。如果你用完这个库,记得调用这个清理函数。
现在说说真正的问题:不幸的是,在2010年12月的NVIDIA SDK中没有NV_GPU_DYNAMIC_PSTATES_INFO_EX
的结构数组,这个结构会包含在过去一秒内某个领域(比如GPU、帧缓冲和视频引擎)的使用率百分比。
基本上,如果你想获取GPU使用信息,你需要把NV_GPU_DYNAMIC_PSTATES_INFO_EX
结构传到Python中(可以参考ctypes文档中的结构和联合),创建一个至少包含3个结构的数组,然后把这个数组传给
顺便提一下,这就是你在初始化时查询的两个函数的作用——它们是一种锁定机制。虽然在调用时并不是严格必要的(也就是说可以省略),但建议你还是调用它们,比如:
Enter()
NvAPI_GPU_GetDynamicPstatesInfoEx(array_of_structs)
Exit()
你应该能够通过查看NVAPI_GPU_UTILIZATION_DOMAIN_GPU这个宏(或常量)来找到GPU使用信息在数组中的位置,不幸的是,SDK的头文件中似乎没有包含这个声明。不过,你可以通过将你的代码结果与NVIDIA系统工具显示的GPU使用信息进行比较来轻松验证这一点。
希望这能帮到你。