DllStructCreate() und DLLCall()

  • Hi,

    ich versuche gerade mich mit DllStructCreate() und DLLCall() zu beschäfftigen, weil ich kein Plan von der Sache habe.
    Als Übung wollte ich die DLL GetCoreTempInfo.dll laden und die Werte entsprechend herauslesen.

    Da ich auch noch keine Ahnung von C/C++ habe, ist der Versuch natürlich misslungen:

    Spoiler anzeigen
    [autoit]


    #cs
    Shared memory implementation in Core Temp:

    [/autoit] [autoit][/autoit] [autoit]

    Core Temp shares the following structure:

    [/autoit] [autoit][/autoit] [autoit]

    typedef struct core_temp_shared_data
    {
    unsigned int uiLoad[256];
    unsigned int uiTjMax[128];
    unsigned int uiCoreCnt;
    unsigned int uiCPUCnt;
    float fTemp[256];
    float fVID;
    float fCPUSpeed;
    float fFSBSpeed;
    float fMultipier;
    char sCPUName[100];
    unsigned char ucFahrenheit;
    unsigned char ucDeltaToTjMax;
    }CORE_TEMP_SHARED_DATA,*PCORE_TEMP_SHARED_DATA,**PPCORE_TEMP_SHARED_DATA;

    [/autoit] [autoit][/autoit] [autoit]

    unsigned int is a 32bit unsigned integer.
    unsigned char is 8bit (1 byte) in size.

    [/autoit] [autoit][/autoit] [autoit]

    ucFahrenheit and ucDeltaToTjMax represent boolean values. 0 = false, 1 = true.
    If ucFahrenheit is set, the temperature is reported in Fahrenheit.
    If ucDeltaToTjMax is set, the temperature reported respresents the distance from TjMax.

    [/autoit] [autoit][/autoit] [autoit]

    Core Temp's shared area is named: "CoreTempMappingObject".

    [/autoit] [autoit][/autoit] [autoit]

    C++ Dynamic Link Library:

    [/autoit] [autoit][/autoit] [autoit]

    This DLL was written in C++, and it can be easily used with most programming languages.
    There is only a single function. Here is the internal function declaration:

    [/autoit] [autoit][/autoit] [autoit]

    bool __declspec(dllimport) fnGetCoreTempInfo(CORE_TEMP_SHARED_DATA *&pData);

    [/autoit] [autoit][/autoit] [autoit]

    You can declare it in your program in the following manner:

    [/autoit] [autoit][/autoit] [autoit]

    typedef bool (*fnGetCoreTempInfo)(CORE_TEMP_SHARED_DATA *&pData);
    fnGetCoreTempInfo GetCoreTempInfo;

    [/autoit] [autoit][/autoit] [autoit]

    For compatibility with some programming languages a function was added.
    It uses Win32 API calling convention and is declared as follows:

    [/autoit] [autoit][/autoit] [autoit]

    bool WINAPI fnGetCoreTempInfoAlt(CORE_TEMP_SHARED_DATA *pData);

    [/autoit] [autoit][/autoit] [autoit]

    typedef bool (*fnGetCoreTempInfoAlt)(CORE_TEMP_SHARED_DATA *pData);
    fnGetCoreTempInfoAlt GetCoreTempInfo;

    [/autoit] [autoit][/autoit] [autoit]

    Usage:

    [/autoit] [autoit][/autoit] [autoit]

    * Declare a pointer to CORE_TEMP_SHARED_DATA structure and allocate it.
    It is also recommended to fill the allocated memory with NULL to avoid possible problems.
    * Call the function using the pointer to CORE_TEMP_SHARED_DATA structure as an argument.
    The function will fill the structure if the shared memory was successfully read.
    * The function returns 'true' if succeeded and 'false' if it failed. You can use GetLastError() in case the function fails.
    * In case the function fails due to an exception GetLastError() returns UNKNOWN_EXCEPTION (0x20000000)
    #ce

    [/autoit] [autoit][/autoit] [autoit]

    $CORE_TEMP_SHARED_DATA = DllStructCreate("uint uiLoad[256];uint uiTjMax[128];uint uiCoreCnt;uint uiCPUCnt;float fTemp[256];float fVID;float fCPUSpeed;float fFSBSpeed;float fMultipier;char sCPUName[100];uchar ucFahrenheit;uchar ucDeltaToTjMax")
    $call = DllCall("GetCoreTempInfo.dll", "ptr", DllStructGetPtr($CORE_TEMP_SHARED_DATA))
    ConsoleWrite(@error & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0,"DllStruct","Struct Size: " & DllStructGetSize($CORE_TEMP_SHARED_DATA) & @CRLF & _
    "Struct pointer: " & DllStructGetPtr($CORE_TEMP_SHARED_DATA) & @CRLF & _
    "Data:" & @CRLF & _
    DllStructGetData($CORE_TEMP_SHARED_DATA,1) & @CRLF & _
    DllStructGetData($CORE_TEMP_SHARED_DATA,2) & @CRLF & _
    DllStructGetData($CORE_TEMP_SHARED_DATA,3) & @CRLF & _
    DllStructGetData($CORE_TEMP_SHARED_DATA,4))
    $CORE_TEMP_SHARED_DATA = 0

    [/autoit]

    Ich bekomme als Error 3 zurück, wenn ich die DLL aufrufe (kann die Funktion in der DLL nicht finden)!

    Bitte um Hilfe!

    DANKE,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (14. Dezember 2009 um 14:47)

  • Dann schmiert AutoIt ab -> AutoIT3.exe ended.rc:-1073741811 (0xC000000D):

    Problemsignatur:
    Problemereignisname: BEX
    Anwendungsname: autoit3.exe
    Anwendungsversion: 3.3.0.0
    Anwendungszeitstempel: 4951fa16
    Fehlermodulname: MSVCR80.dll
    Fehlermodulversion: 8.0.50727.4016
    Fehlermodulzeitstempel: 49cc5361
    Ausnahmeoffset: 00050458
    Ausnahmecode: c000000d
    Ausnahmedaten: 00000000
    Betriebsystemversion: 6.0.6002.2.2.0.256.4
    Gebietsschema-ID: 1031
    Zusatzinformation 1: f8e2
    Zusatzinformation 2: d04fb6ee658f7d3cee66529a2d481744
    Zusatzinformation 3: cee4
    Zusatzinformation 4: a036d36cbb9a043e18b9e0e91c87e6cd

    Lesen Sie unsere Datenschutzrichtlinie:
    http://go.microsoft.com/fwlink/?linkid=50163&clcid=0x0407

    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • komisch, sonst geht das eigtl. ?(
    ansonsten könntest du noch die andere Funktion "fnGetCoreTempInfoAlt" probieren

    Zitat

    For compatibility with some programming languages a function was added.
    It uses Win32 API calling convention and is declared as follows:

    bool WINAPI fnGetCoreTempInfoAlt(CORE_TEMP_SHARED_DATA *pData);

    typedef bool (*fnGetCoreTempInfoAlt)(CORE_TEMP_SHARED_DATA *pData);
    fnGetCoreTempInfoAlt GetCoreTempInfo;

  • Habe ich auch bereits getestet - gleiches Problem.

    Bald fange ich auch richtig mit C/C++ an, habe bereits "Hello World" in C++ erstellt (krass)! :thumbup:

    Ich verstehe nicht ganz die C++ Strukturen, um den beigefügten Text richtig zu folgen! ?(

    Danke,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Danke Ahnungslos (obwohl ich es bin :D )! uchar gibt es nicht als Typ. Wenn ich char nehme, bekomme ich was zurück!

    [autoit]


    $dll = DllOpen("GetCoreTempInfo.dll")
    $CORE_TEMP_SHARED_DATA = DllStructCreate("uint uiLoad[256];uint uiTjMax[128];uint uiCoreCnt;uint uiCPUCnt;float fTemp[256];float fVID;float fCPUSpeed;float fFSBSpeed;float fMultipier;char sCPUName[100];char ucFahrenheit;char ucDeltaToTjMax")
    $call = DllCall($dll, "int", "fnGetCoreTempInfoAlt", "ptr", DllStructGetPtr($CORE_TEMP_SHARED_DATA))
    ConsoleWrite(@error & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    MsgBox(0,"DllStruct","Struct Size: " & DllStructGetSize($CORE_TEMP_SHARED_DATA) & @CRLF & _
    "Struct pointer: " & DllStructGetPtr($CORE_TEMP_SHARED_DATA) & @CRLF & _
    "CPU Speed: " & DllStructGetData($CORE_TEMP_SHARED_DATA, "fCPUSpeed"))
    $CORE_TEMP_SHARED_DATA = 0
    DllClose($dll)

    [/autoit]

    Danke,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • beim drüberschaun ist mir auch gerade noch aufgefallen:
    müsste es nicht statt char byte und statt uchar ubyte heißen?

    edit: C++ hab ich auch mal begonnen und sehr schnell das Interessa dran verloren,
    find Nasm da toller, nur leider meckert mein Vierenscanner einige Programme danach an 8|

    ASM ist auch interessant, könnte es für einige zeitkritische Operationen in GDI+ benutzen, wenn ich nur ASM könnte!

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Wie bekomme ich alle Werte für float fTemp[256] zurück?

    $CPU_Temp = DllStructGetData($CORE_TEMP_SHARED_DATA, "fTemp") liefert mir nur ein Wert zurück, erwarte aber 2 Werte!

    $CPU_Temp ist kein Array!

    Danke,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hab's: $CPU_Temp = DllStructGetData($CORE_TEMP_SHARED_DATA, "fTemp", [index])

    Wie viele Indices wurden benutzt? Kann man das herausbekommen?

    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Ich denke, etwa so sollte es funktionieren:

    Spoiler anzeigen
    [autoit]

    #include<WinAPi.au3>
    Global Const $tagCORE_TEMP_SHARED_DATA = _
    "uint uiLoad[256];" & _
    "uint uiTjMax[128];" & _
    "uint uiCoreCnt;" & _
    "uint uiCPUCnt;" & _
    "float fTemp[256];" & _
    "float fVID;" & _
    "float fCPUSpeed;" & _
    "float fFSBSpeed;" & _
    "float fMultipier; " & _
    "char sCPUName[100];" & _
    "byte ucFahrenheit;" & _
    "byte ucDeltaToTjMax;"

    [/autoit] [autoit][/autoit] [autoit]

    Switch @AutoItX64
    Case True
    Global $ghGetCoreTempInfoDLL = DllOpen(@ScriptDir & "\x64\GetCoreTempInfo.dll")
    Case Else
    Global $ghGetCoreTempInfoDLL = DllOpen(@ScriptDir & "\x86\GetCoreTempInfo.dll")
    EndSwitch
    If $ghGetCoreTempInfoDLL = -1 Then Exit MsgBox(0, '', "Error on loading DLL")

    [/autoit] [autoit][/autoit] [autoit]

    $tCORE_TEMP_SHARED_DATA = DllStructCreate($tagCORE_TEMP_SHARED_DATA)
    $lpCORE_TEMP_SHARED_DATA = DllStructGetPtr($tCORE_TEMP_SHARED_DATA)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ Local $aResult = DllCall($ghGetCoreTempInfoDLL, "int:cdecl", 'fnGetCoreTempInfo', 'ptr', $lpCORE_TEMP_SHARED_DATA)
    Local $aResult = DllCall($ghGetCoreTempInfoDLL, "int", 'fnGetCoreTempInfoAlt', 'ptr', $lpCORE_TEMP_SHARED_DATA)
    If @error Then Exit MsgBox(0, '', "error on DLLCall")

    [/autoit] [autoit][/autoit] [autoit]

    If Not $aResult[0] Then Exit MsgBox(0, '', "Error on querying CPU temp")

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, '', DllStructGetData($tCORE_TEMP_SHARED_DATA, 'sCPUName'))

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To DllStructGetData($tCORE_TEMP_SHARED_DATA, 'uiCoreCnt')
    MsgBox(0, 'Core ' & $i, DllStructGetData($tCORE_TEMP_SHARED_DATA, 'fTemp', $i))
    Next

    [/autoit]

    PS: wer es testen will: CoreTemp muss dabei laufen, sonst wird nichts gefunden.

  • Danke progandy!


    Hier meine Version:

    Spoiler anzeigen
    [autoit]


    If Not FileExists(@ScriptDir & "\GetCoreTempInfo.dll") Or Not ProcessExists("Core Temp.exe") Then
    MsgBox(16,"Error", "Core Temp.exe läuft und/oder GetCoreTempInfo.dll existiert nicht", 20)
    Exit
    EndIf
    $dll = DllOpen(@ScriptDir & "\GetCoreTempInfo.dll")
    $CORE_TEMP_SHARED_DATA = DllStructCreate("uint uiLoad[256];uint uiTjMax[128];uint uiCoreCnt;uint uiCPUCnt;float fTemp[256];float fVID;float fCPUSpeed;float fFSBSpeed;float fMultipier;char sCPUName[100];ubyte ucFahrenheit;ubyte ucDeltaToTjMax")
    $call = DllCall($dll, "int", "fnGetCoreTempInfoAlt", "ptr", DllStructGetPtr($CORE_TEMP_SHARED_DATA))

    [/autoit] [autoit][/autoit] [autoit]

    $CPU_Name = DllStructGetData($CORE_TEMP_SHARED_DATA, "sCPUName")
    $CPU_Speed = Round(DllStructGetData($CORE_TEMP_SHARED_DATA, "fCPUSpeed"),0)
    $CPU_Cores = DllStructGetData($CORE_TEMP_SHARED_DATA, "uiCoreCnt")
    $CPU_FSB_Speed = Round(DllStructGetData($CORE_TEMP_SHARED_DATA, "fFSBSpeed"), 0)
    $CPU_Multiplicator = DllStructGetData($CORE_TEMP_SHARED_DATA, "fMultipier")
    $CPU_Temp = ""
    For $i = 1 To DllStructGetData($CORE_TEMP_SHARED_DATA, 'uiCoreCnt')
    $CPU_Temp &= DllStructGetData($CORE_TEMP_SHARED_DATA, "fTemp", $i) & ","
    Next
    $CPU_Temp = StringMid($CPU_Temp, 1 , StringLen($CPU_Temp) - 1)

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0,"Core Temp", _
    "CPU Name: " & $CPU_Name & @CRLF & _
    "CPU Speed: " & $CPU_Speed & " MHz" & @CRLF & _
    "CPU Cores: " & $CPU_Cores & @CRLF & _
    "CPU FSB Speed: " & $CPU_FSB_Speed & " MHz" & @CRLF & _
    "CPU Multiplicator: " & $CPU_Multiplicator & @CRLF & _
    "CPU Temp: " & $CPU_Temp & " C")
    $CORE_TEMP_SHARED_DATA = 0
    DllClose($dll)

    [/autoit]

    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (14. Dezember 2009 um 16:39)