Sign in to follow this  
Followers 0
Anas

C#\C++ to Autoit

18 posts in this topic

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.

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

If this works then you must swear your eternal allegiance to me.

Edit: Forgot to mention that the latest beta is required.

; 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 by jaberwocky6669

Share this post


Link to post
Share on other sites

You have my eternal allegiance ... when the script works :P

 

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?

Share this post


Link to post
Share on other sites

I really appreciate the effort, thanks :)

Share this post


Link to post
Share on other sites

#6 ·  Posted (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..

Dim $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 by Ascend4nt
1 person likes this

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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 :lol:

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

Share this post


Link to post
Share on other sites

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 :P 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.

Share this post


Link to post
Share on other sites

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).

Share this post


Link to post
Share on other sites

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.

#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

Share this post


Link to post
Share on other sites

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..

Share this post


Link to post
Share on other sites

#14 ·  Posted (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):
 

internal 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)?

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
    $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 by Anas

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

 

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;")

Share this post


Link to post
Share on other sites

#18 ·  Posted (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 by Anas

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0