Anas Posted July 23, 2013 Share Posted July 23, 2013 Hello, I'm trying to convert a C#C++ to Autoit, but since I don't understand neither of them (nor DLL for that matter) I'm having a hard time.. So, I hope some one can explain to me how to or convert a single function so I can build on it. C++http://eliang.blogspot.com/2011/05/getting-nvidia-gpu-usage-in-c.html C# https://code.google.com/p/open-hardware-monitor/source/browse/trunk/Hardware/Nvidia/NVAPI.cs #include <Array.au3> #include <WinAPI.au3> Dim $DLL = DllOpen('nvapi.dll'), $NVAPI_MAX_PHYSICAL_GPUS = 64, $NVAPI_MAX_USAGES_PER_GPU = 34 Dim $NvStatus, $GpuCount, $GpuHanldes[ $NVAPI_MAX_PHYSICAL_GPUS ], $GpuUsages[ $NVAPI_MAX_USAGES_PER_GPU ] NvAPI_Initialize() $R = NvAPI_EnumPhysicalGPUs() _ArrayDisplay($GpuHanldes) MsgBox(0, '', $GpuCount) DllClose($DLL) Func NvAPI_Initialize() $result = DllCall($DLL, "int:cdecl", 'nvapi_QueryInterface', 'int', 0x0150E828, 'int', $NvStatus) If @error Then Exit MsgBox(16, 'Error!', 'Initialization Failed!' & @CRLF & @error) Return $result EndFunc Func NvAPI_EnumPhysicalGPUs() $result = DllCall($DLL, "int:cdecl", 'nvapi_QueryInterface', 'int', 0xE5AC921F, 'int', $GpuHanldes, 'int', $GpuCount) If @error Then Exit MsgBox(16, 'Error!', 'Enumeration Failed!' & @CRLF & @error) Return $result EndFunc Func NvAPI_GPU_GetUsages() $result = DllCall($DLL, "int:cdecl", 'nvapi_QueryInterface', 'int', 0x189A1FDF, 'int', $GpuHanldes[0], 'uint', $GpuUsages) If @error Then Exit MsgBox(16, 'Error!', 'Getting Usages Failed' & @CRLF & @error) Return $result EndFunc Thanks. Link to comment Share on other sites More sharing options...
jaberwacky Posted July 23, 2013 Share Posted July 23, 2013 (edited) If this works then you must swear your eternal allegiance to me. Edit: Forgot to mention that the latest beta is required. expandcollapse popup; Getting Nvidia GPU Usage ; Reference: Open Hardware Monitor (http:;code.google.com/p/open-hardware-monitor) ; magic numbers, do not change them Global Const $NVAPI_MAX_PHYSICAL_GPUS = 64 Global Const $NVAPI_MAX_USAGES_PER_GPU = 34 main func main() local $hmod = DllOpen("nvapi.dll") if $hmod = -1 then ConsoleWrite("Couldn't find nvapi.dll" & @crlf) return SetError(1, 0, False) EndIf ; nvapi_QueryInterface is a function used to retrieve other internal functions in nvapi.dll local $NvAPI_QueryInterface = DllCall("Kernel32.dll", "ptr", "GetProcAddress", "ptr", $hmod, "str", "nvapi_QueryInterface")[0] ; some useful internal functions that aren't exported by nvapi.dll local $NvAPI_Initialize = $NvAPI_QueryInterface(0x0150E828) local $NvAPI_EnumPhysicalGPUs = $NvAPI_QueryInterface(0xE5AC921F) local $NvAPI_GPU_GetUsages = $NvAPI_QueryInterface(0x189A1FDF) if $NvAPI_Initialize = NULL or $NvAPI_EnumPhysicalGPUs = NULL or $NvAPI_EnumPhysicalGPUs = NULL or $NvAPI_GPU_GetUsages = NULL then ConsoleWrite("Couldn't get functions in nvapi.dll" & @CRLF) return SetError(2, 0, False) endif ; initialize NvAPI library, call it once before calling any other NvAPI functions $NvAPI_Initialize() local $gpuCount = 0 local $gpuHandles[$NVAPI_MAX_PHYSICAL_GPUS] = NULL local $gpuUsages[$NVAPI_MAX_USAGES_PER_GPU] = [0] ; gpuUsages[0] must be this value, otherwise NvAPI_GPU_GetUsages won't work $gpuUsages[0] = BitOr($NVAPI_MAX_USAGES_PER_GPU * 4, 0x10000) $NvAPI_EnumPhysicalGPUs($gpuHandles, $gpuCount) ; print GPU usage every second for $i = 0 to 99 $NvAPI_GPU_GetUsages($gpuHandles[0], $gpuUsages) $usage = $gpuUsages[3] ConsoleWrite("GPU Usage: " & $usage & @CRLF) Sleep(1000) next return True EndFunc  UNTESTED! Edited July 23, 2013 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Anas Posted July 23, 2013 Author Share Posted July 23, 2013 You have my eternal allegiance ... when the script works  I get this in SciTE: >"E:\Admin\Desktop\autoit-v3.3.9.11\install\SciTe\..\autoit3.exe" /ErrorStdOut "E:\Admin\Desktop\aa.au3" "E:\Admin\Desktop\aa.au3" (22) : ==> Variable cannot be accessed in this manner.: local $NvAPI_Initialize = $NvAPI_QueryInterface(0x0150E828) local $NvAPI_Initialize = $NvAPI_QueryInterface^ ERROR >Exit code: 1 Time: 0.049 I thought "GetProcAddress" was not needed, since DLLCall do it for me? Link to comment Share on other sites More sharing options...
jaberwacky Posted July 23, 2013 Share Posted July 23, 2013 Aw shoot, I was hoping that the functions would be stored in those variables. I guess not. Sorry. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Anas Posted July 23, 2013 Author Share Posted July 23, 2013 I really appreciate the effort, thanks Link to comment Share on other sites More sharing options...
Solution Ascend4nt Posted July 23, 2013 Solution Share Posted July 23, 2013 (edited) Just messing around with it, this is what it looks like might be on the right track.. You need pointers to the functions, and the array has to be a DLLStruct.. I was lazy and didnt' declare most variables though. And I can't test it.. expandcollapse popupDim $DLL = DllOpen('nvapi.dll') $N = NvAPI_Initialize() ConsoleWrite("Return = " & $N & ", @error = " & @error & ", @extended = " & @extended & @CRLF) $R = NvAPI_EnumPhysicalGPUs() _ArrayDisplay($R) For $i = 0 To 100 NvAPI_GPU_GetUsages($R[0]) Sleep(1000) Next DllClose($DLL) Func NvAPI_QueryInterface($nInterface) $result = DllCall($DLL, "ptr:cdecl", 'nvapi_QueryInterface', 'int', $nInterface) If @error Then Return SetError(2,@error,0) If $result[0] = 0 Then Return SetError(3,0,0) Return $result[0] EndFunc Func NvAPI_Initialize() Static Local $pInitialize = 0 If $pInitialize = 0 Then $pInitialize = NvAPI_QueryInterface(0x0150E828) If $pInitialize = 0 Then Return SetError(@error,@extended,0) EndIf $result = DllCallAddress("int:cdecl", $pInitialize) If @error Then Return SetError(2,@error,False) Return $result[0] EndFunc Func NvAPI_EnumPhysicalGPUs() Static Local $pEnumPhysGPUs = 0 If $pEnumPhysGPUs = 0 Then $pEnumPhysGPUs = NvAPI_QueryInterface(0xE5AC921F) If $pEnumPhysGPUs = 0 Then Return SetError(@error, @extended, 0) EndIf $stGPUHandles = DllStructCreate("ptr gpuHandles[64];") $result = DllCallAddress("int:cdecl", $pEnumPhysGPUs, 'ptr', DllStructGetPtr($stGPUHandles), 'int*', 0) If @error Then Return SetError(2,@error,0) If $result[0] Then Return SetError(3,0,0) $nGPUCount = $result[2] Dim $result[$nGPUCount] For $i = 1 To $nGPUCount $result[$i - 1] = DllStructGetData($stGPUHandles, 1, $i) Next Return $result EndFunc Func NvAPI_GPU_GetUsages($vGPUHandle) Static Local $pGetUsages = 0 If $pGetUsages = 0 Then $pGetUsages = NvAPI_QueryInterface(0x189A1FDF) If $pGetUsages = 0 Then Return SetError(@error, @extended, 0) EndIf $stGPUUsages = DllStructCreate("uint gpuUsages[34];") DLLStructSetData($stGPUUsages, 1, BitOR(34 * 4, 0x10000), 1) $result = DllCallAddress("int:cdecl", $pGetUsages, 'ptr', $vGPUHandle, 'ptr', DllStructGetPtr($stGPUUsages)) If @error Then Return SetError(2,@error,0) If $result[0] Then Return SetError(3, 0, 0) Return DllStructGetData($stGPUUsages, 1, 4) ; 4 is equivalent to c's array[3] EndFunc *edit: Fixed parameters and parameter return check (non-zero is error).. AND indexing. Still not sure its entirely kosher though Edited July 23, 2013 by Ascend4nt jaberwacky 1 My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
jaberwacky Posted July 23, 2013 Share Posted July 23, 2013 Cool! Even if it doesn't work, I can learn a lot from your code. Thanks. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Anas Posted July 23, 2013 Author Share Posted July 23, 2013 Hello Ascend4nt, I'm not sure about "NvAPI_Initialize" since it should return 0 (according to the C# link), but I get an error 3 from "NvAPI_EnumPhysicalGPUs", the array returned from it has a value of 0 in $result[0], but not in $result[1] and $result[2], and if I comment the return lines out, I keep getting 0 for usage. if you don't mind, can you answer a few questions: - Does all Arrays have to be a DLLStruct for autoit? (I didn't see a Struct in the C++ link) - Why did you use a "ptr" in the gpuHandles struct? - Why did you not use a "unit" in the gpuCount struct? Thank you for your help and time. Link to comment Share on other sites More sharing options...
Ascend4nt Posted July 23, 2013 Share Posted July 23, 2013 Anas, so some of the code was wrong. I was half-assing it really as I was talking to some blabbermouth on the phone at the time, hahah Anyway.. I THINK it now more correctly follows the code example, although I really have no idea if it will work. I think this is one of the worst ways to go about calling functions, for 2 reasons: 1) the size and offset of code will change with every version - you will need to connect this code with a SPECIFIC version of nvapi.dll; 2) calling functions that aren't exported is never ever a good idea. Oh, and I should mention that you'll need to force the script to run in x86 (32-bit mode). Now.. as for the questions.. - All arrays passed to a DLL must be passed through Structs, yes. AutoIt's arrays can not be accessed through pointers. They are variants which are maintained internally, and can be a mixture of any types. - gpuHandles are pointers because thats what they are! 'int *' is a pointer to an int. AutoIt's DllStructs don't know what the data is that is being pointed to, only that the underlying type is a pointer. (Oh, and an int ** is an array of pointers) - The 'uint' was a mistake. As were a few other things. Give it a try, maybe it works somewhat now. Looks more like the C code.. I just really really think its a bad idea though. DLL's should be interacted with through exported functions My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
Anas Posted July 23, 2013 Author Share Posted July 23, 2013 Hello Ascend4nt, I hope you didn't misunderstand me, I wasn't trying to point mistakes out, just trying to clear things out and figure what their values should be... Anyway, It's working now, I'll try to add the other functions to it and see how far I can go. Unfortunately, I can't read those sensors without it, since nVidia made a ".lib", as for the version, I think I can update it using Hardware Monitor code. one last question do you have a source that I can learn how to interact with dlls from? or Must I learn C++? Thank you Ascend4nt, Much appreciated. Link to comment Share on other sites More sharing options...
Ascend4nt Posted July 23, 2013 Share Posted July 23, 2013 To interact with DLL's, just look around the forums, many of the big projects use DLLCall, and certainly many of the include files from AutoIt. If you don't know C/C++, it'll be a problem porting things over. It's an even bigger pain when APIs are described in types that aren't defined (which is why it helps to have a Windows SDK to look those types up). My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
Anas Posted July 24, 2013 Author Share Posted July 24, 2013 Hello, I've been trying to add (NvAPI_GPU_GetMemoryInfo) and (NvAPI_GPU_GetThermalSettings) from the C# link, but I keep getting (-9) "INCOMPATIBLE_STRUCT_VERSION", I can't get their structs correctly. expandcollapse popup#include <Array.au3> Dim $gpuHwnds[1], $disHwnds[1], $PhyGpuDisHwnds[1] Dim $DLL = DllOpen('nvapi.dll') $N = NvAPI_Initialize() NvAPI_EnumPhysicalGPUs() NvAPI_EnumNvidiaDisplayHandle() NvAPI_GetPhysicalGPUsFromDisplay($disHwnds[1]) NvAPI_GPU_GetThermalSettings($disHwnds[1]) Exit NvAPI_GPU_GetMemoryInfo($disHwnds[1]) For $i = 0 To 10 $Usage = NvAPI_GPU_GetUsages($gpuHwnds[1]) ConsoleWrite('Usage ' & $Usage & @CRLF) Sleep(1000) Next DllClose($DLL) Func NvAPI_QueryInterface($nInterface) $result = DllCall($DLL, "ptr:cdecl", 'nvapi_QueryInterface', 'int', $nInterface) If @error Then Return SetError(2,@error,0) If $result[0] = 0 Then Return SetError(3,0,0) Return $result[0] EndFunc Func NvAPI_Initialize() Static Local $pInitialize = 0 If $pInitialize = 0 Then $pInitialize = NvAPI_QueryInterface(0x0150E828) If $pInitialize = 0 Then Return SetError(@error,@extended,0) EndIf $result = DllCallAddress("int:cdecl", $pInitialize) If @error Then Return SetError(2,@error,False) Return $result[0] EndFunc Func NvAPI_EnumPhysicalGPUs() Static Local $pEnumPhysGPUs = 0 If $pEnumPhysGPUs = 0 Then $pEnumPhysGPUs = NvAPI_QueryInterface(0xE5AC921F) If $pEnumPhysGPUs = 0 Then Return SetError(@error, @extended, 0) EndIf $stGPUHandles = DllStructCreate("INT_PTR gpuHandles[64];") $result = DllCallAddress("int:cdecl", $pEnumPhysGPUs, 'ptr', DllStructGetPtr($stGPUHandles), 'int*', 0) If @error Then Return SetError(2,@error,0) If $result[0] Then Return SetError(3,0,0) $gpuHwnds[0] = $result[2] For $i = 1 To $gpuHwnds[0] _ArrayAdd($gpuHwnds, DllStructGetData($stGPUHandles, 1, $i)) Next Return EndFunc Func NvAPI_GPU_GetUsages($vGPUHandle) Static Local $pGetUsages = 0 If $pGetUsages = 0 Then $pGetUsages = NvAPI_QueryInterface(0x189A1FDF) If $pGetUsages = 0 Then Return SetError(@error, @extended, 0) EndIf $stGPUUsages = DllStructCreate("uint gpuUsages[34];") DLLStructSetData($stGPUUsages, 1, BitOR(34 * 4, 0x10000), 1) $result = DllCallAddress("int:cdecl", $pGetUsages, 'ptr', $vGPUHandle, 'ptr', DllStructGetPtr($stGPUUsages)) If @error Then Return SetError(2,@error,0) If $result[0] Then Return SetError(3, 0, 0) Return DllStructGetData($stGPUUsages, 1, 4) ; 4 is equivalent to c's array[3] EndFunc Func NvAPI_EnumNvidiaDisplayHandle() Static Local $pEnumDisHwnd = 0 If $pEnumDisHwnd = 0 Then $pEnumDisHwnd = NvAPI_QueryInterface(0x9ABDD40D) If $pEnumDisHwnd = 0 Then Return SetError(@error, @extended, 0) EndIf $stDisHandles = DllStructCreate("PTR dispHandle;") $i = 0 While 1 $result = DllCallAddress("int:cdecl", $pEnumDisHwnd, 'int', $i, 'ptr', DllStructGetPtr($stDisHandles)) If @error Then Return SetError(2,@error,0) If $result[0] And $i = 0 Then Return SetError(3,0,0) If $result[0] Then ExitLoop _ArrayAdd($disHwnds, DllStructGetData($stDisHandles, 1)) $disHwnds[0] = $i + 1 $i += 1 WEnd EndFunc Func NvAPI_GetPhysicalGPUsFromDisplay($vdisHandle) Static Local $pPhysGPUsDisp = 0 If $pPhysGPUsDisp = 0 Then $pPhysGPUsDisp = NvAPI_QueryInterface(0x34EF9506) If $pPhysGPUsDisp = 0 Then Return SetError(@error, @extended, 0) EndIf $stGPUHandles = DllStructCreate("INT_PTR PgpuHandles[64];") ; was ptr only $result = DllCallAddress("int:cdecl", $pPhysGPUsDisp, 'ptr', $vdisHandle, 'ptr', DllStructGetPtr($stGPUHandles), 'int*', 0) If @error Then Return SetError(2,@error,0) If $result[0] Then Return SetError(3,0,0) $PhyGpuDisHwnds[0] = $result[3] For $i = 1 To $PhyGpuDisHwnds[0] _ArrayAdd($PhyGpuDisHwnds, DllStructGetData($stGPUHandles, 1, $i)) Next EndFunc ;===================;===================;===================;===================;===================;===================;=================== Func NvAPI_GPU_GetMemoryInfo($vdisHandle) Static Local $pMemInfo = 0 If $pMemInfo = 0 Then $pMemInfo = NvAPI_QueryInterface(0x774AA982) If $pMemInfo = 0 Then Return SetError(@error, @extended, 0) EndIf $NvMemoryInfo = DllStructCreate("uint values[5];") ;DLLStructSetData($NvMemoryInfo, 1, 0x20000, 1) $result = DllCallAddress("int:cdecl", $pMemInfo, 'ptr', $vdisHandle, 'ptr', DllStructGetPtr($NvMemoryInfo)) _ArrayDisplay($result, 'Memory') If @error Then Return SetError(2,@error,0) If $result[0] Then Return SetError(3,0,0) Return $result EndFunc Func NvAPI_GPU_GetThermalSettings($vGPUHandle) Static Local $pThermalInfo = 0 If $pThermalInfo = 0 Then $pThermalInfo = NvAPI_QueryInterface(0xE3640A56) If $pThermalInfo = 0 Then Return SetError(@error, @extended, 0) EndIf $NvSensorStruct = 'uint Controller;uint DefaultMinTemp;uint DefaultMaxTemp;uint CurrentTemp;uint Target;' $NvSensor = DllStructCreate($NvSensorStruct) ;DllStructSetData($NvSensor, 'Controller', 1) ;DllStructSetData($NvSensor, 'Target', 1) $NvGPUThermalSettings = DllStructCreate('uint Version;uint Count[3];ptr ' & DllStructGetPtr($NvSensor)) ;STRUCT' & $NvSensorStruct & 'ENDSTRUCT;');& DllStructCreate($$NvSensorStruct)) $result = DllCallAddress("int:cdecl", $pThermalInfo, 'ptr', $vGPUHandle, 'int', 0, 'ptr', DllStructGetPtr($NvGPUThermalSettings)) _ArrayDisplay($result, 'Thermal') If @error Then Return SetError(2,@error,0) If $result[0] Then Return SetError(3,0,0) Return $result EndFunc Link to comment Share on other sites More sharing options...
Ascend4nt Posted July 25, 2013 Share Posted July 25, 2013 Anas, why did you change 'ptr' to 'int_ptr'? They are the same width and are functionally the same. The only difference is internally AutoIt sees one as a pointer and the other as a number, though both can be used interchangeably. Also, there's no reason to replace the array dimensions with_ArrayAdd(). Its both slow and unnecessary. The # of elements to be put into the array is known before hand, so either size the array to accommodate the data, or ReDim it to add extra data. Typically only use it if you are getting a variable # of elements. Ah, and be sure to declare all variables, as Local whenever possible. My example didn't declare any, which is AWFUL practice and should be avoided at all costs. (I said I was lazy!) I see you've declared a few things Global - that isn't necessary if your functions return arrays. I haven't looked to much at the C# code yet, and most of C# is easy but wtf is this?: [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)] Does that modify the array declaration that follows? I'd take a guess that it does. In which case, NvSensor[] Sensor; would be NvSensor[MAX_THERMAL_SENSORS_PER_GPU]. Which I'm assuming is a pointer to an array, and not an array of pointers?.. I'm a bit unclear what it is defining. Also, I see this in your code: $NvGPUThermalSettings = DllStructCreate('uint Version;uint Count[3];ptr ' & DllStructGetPtr($NvSensor)) That's a fail. If you're trying to set the pointer, you have to use DLLStructSetData. Be sure to litter your code with @error checks and ConsoleWrite()'s to make sure you understand what code is failing (like the above). There's also other tools like _DLLStructDisplay (someone might have that in their signature). Anyway, that's all I'm up for analyzing at the moment.. My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
Anas Posted July 25, 2013 Author Share Posted July 25, 2013 (edited) Hello Ascend4nt, When I saw it in the C# code used as int_ptr I switched it to match, as for tidying up the code and declaring variables, I'll do it when I finish, since this is going to be a part of another script. I figured out what war wrong with NvAPI_GPU_GetMemoryInfo, but what I'm still struggling with is NvAPI_GPU_GetThermalSettings He is referencing structs/enums (Named Enums?) within structs (or at least that what I think): Â expandcollapse popupinternal enum NvThermalController { NONE = 0, GPU_INTERNAL, ADM1032, MAX6649, MAX1617, LM99, LM89, LM64, ADT7473, SBMAX6649, VBIOSEVT, OS, UNKNOWN = -1, } internal enum NvThermalTarget { NONE = 0, GPU = 1, MEMORY = 2, POWER_SUPPLY = 4, BOARD = 8, ALL = 15, UNKNOWN = -1 }; [StructLayout(LayoutKind.Sequential, Pack = 8)] internal struct NvSensor { public NvThermalController Controller; public uint DefaultMinTemp; public uint DefaultMaxTemp; public uint CurrentTemp; public NvThermalTarget Target; } [StructLayout(LayoutKind.Sequential, Pack = 8)] internal struct NvGPUThermalSettings { public uint Version; public uint Count; [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)] public NvSensor[] Sensor; } I've no idea how to accomplish that, should I create structs for the enums and then reference them using a ';ptr DllStructSetData(DllStructGetPtr)? expandcollapse popupFunc NvAPI_GPU_GetThermalSettings($vGPUHandle) Static Local $pThermalInfo = 0 If $pThermalInfo = 0 Then $pThermalInfo = NvAPI_QueryInterface(0xE3640A56) If $pThermalInfo = 0 Then Return SetError(@error, @extended, 0) EndIf $NvThermalCtrlStruct = 'int NONE;int GPU_INTERNAL;int ADM1032;int MAX6649;int MAX1617;int LM99;int LM89;int LM64;int ADT7473;int SBMAX6649;int VBIOSEVT;int OS;int UNKNOWN;' $NvThermalController = DllStructCreate($NvThermalCtrlStruct) For $i = 2 To 12 DllStructSetData($NvThermalController, $i, $i - 1) Next DllStructSetData($NvThermalController, 13, -1) _DLLStructDisplay($NvThermalController, $NvThermalCtrlStruct, 'Controller') $NvThermalTgtStruct = 'int NONE;int GPU;int MEMORY;int POWER_SUPPLY;int BOARD;int ALL;int UNKNOWN;' $NvThermalTarget = DllStructCreate($NvThermalTgtStruct) DllStructSetData($NvThermalTarget, 1, 0) DllStructSetData($NvThermalTarget, 2, 1) DllStructSetData($NvThermalTarget, 3, 2) DllStructSetData($NvThermalTarget, 4, 4) DllStructSetData($NvThermalTarget, 5, 8) DllStructSetData($NvThermalTarget, 6, 15) DllStructSetData($NvThermalTarget, 7, -1) _DLLStructDisplay($NvThermalTarget, $NvThermalTgtStruct, 'Target') $NvSensorStruct = 'ptr Controller;uint DefaultMinTemp;uint DefaultMaxTemp;uint CurrentTemp;ptr Target;' $NvSensor = DllStructCreate($NvSensorStruct) DllStructSetData($NvSensor, 'Controller', DllStructGetPtr($NvThermalController)) DllStructSetData($NvSensor, 'Target', DllStructGetPtr($NvThermalTarget)) _DLLStructDisplay($NvSensor, $NvSensorStruct, 'Sensor') $NvGPUThermalStsStruct = 'uint Version;uint Count;ptr Sensors[3];' $NvGPUThermalSettings = DllStructCreate($NvGPUThermalStsStruct) DLLStructSetData($NvGPUThermalSettings, 'Version', BitOR(DllStructGetSize($NvGPUThermalSettings), 0x10000), 1) ;DLLStructSetData($NvGPUThermalSettings, 'Count', 3, 1) DllStructSetData($NvGPUThermalSettings, 'Sensors', DllStructGetPtr($NvSensor)) _DLLStructDisplay($NvGPUThermalSettings, $NvGPUThermalStsStruct, 'Settings') $result = DllCallAddress("int:cdecl", $pThermalInfo, 'ptr', $vGPUHandle, 'int', 0, 'ptr', DllStructGetPtr($NvGPUThermalSettings)) _ArrayDisplay($result, 'Thermal') If @error Then Return SetError(2,@error,0) If $result[0] Then Return SetError(3,0,0) Return $result EndFunc Edited July 25, 2013 by Anas Link to comment Share on other sites More sharing options...
jaberwacky Posted July 25, 2013 Share Posted July 25, 2013 I guess for example: NvGPUThermalSettings.Controller.GPU_INTERNAL ? Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Anas Posted July 26, 2013 Author Share Posted July 26, 2013 Hello Jaber, I'm not sure how to use that, and it seems that it's missing the "Sensor[]" part. I've been testing structs;endstruct and/or combining the structs into one, but none of them worked. What is throwing me off the most is that the substruct "NvSensor" is suppose to be an array?! I'm starting to doubt that such struct is not possible with autoit, or I'm way off track and my approach is completely wrong. Link to comment Share on other sites More sharing options...
Ascend4nt Posted July 30, 2013 Share Posted July 30, 2013  Hello Ascend4nt, When I saw it in the C# code used as int_ptr I switched it to match, as for tidying up the code and declaring variables, I'll do it when I finish, since this is going to be a part of another script. I figured out what war wrong with NvAPI_GPU_GetMemoryInfo, but what I'm still struggling with is NvAPI_GPU_GetThermalSettings He is referencing structs/enums (Named Enums?) within structs (or at least that what I think): ...  'int*' and 'int_ptr' aren't really the same concept, although they look the same. Basically int_ptr means an integer the size of a pointer, which is dependent on the bit mode of the script and O/S. (ptr and int_ptr both equal 64-bits on a 64-bit process, and 32-bits on a 32-bit process) As far as enumerations, those are simply a range of values an integer can be. So you only need to define one "int" for the entire enumeration. So NvSensor becomes: $stNvSensor = DLLStructCreate("int Controller;uint DefaultMinTemp;uint DefaultMaxTemp;uint CurrentTemp;int Target;") My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
Anas Posted July 31, 2013 Author Share Posted July 31, 2013 (edited) Hello Ascend4nt, I've tried that (among many things), but since I don't know how to pass the NVSensor struct as an array, it didn't work. anyway, thanks to ProgAndy (>Nested DllStructs), I managed to get it to work in seconds. Thanks for the help Edited July 31, 2013 by Anas Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now