DllCall und Array als Parameter

  • Hallo zusammen,
    ich habe leider nicht so viel Erfahrung mit DllCall deswegen brauche ich eure Unterstütung.
    Ich will mit DllCall eine Funktion einer DLL aufrufen, welche als Parameter unter anderem einen Array aus Strings erwartet.
    Nun habe ich in AutoIt folgenden Code geschrieben:

    [autoit]


    Global $arrGroups[2] = ["GROUP1","GROUP2"]
    $objDll = DllOpen("SMSRsGen.dll")
    $intResult = DllCall($objDll, "int", "DDRAddStringArray", "str", "System Group Name", "ptr", $arrGroups, "int", 2, "int", 64, "dword", 16)
    DllClose($objDll)

    [/autoit]

    Die Referenz zu der Funktion findet ihr hier:
    http://msdn.microsoft.com/en-us/library/cc144899.aspx

    So wie es im Beispiel ist, funktioniert es nicht. Ich weiss aber nicht wie ich das Array $arrGroups da übergeben kann.

    Vielen Dank schon mal für die Hilfe!

  • Hallo funkey
    diese Idee ist mir auch schon gekommen aber ein bekannter C Programmierer hat mir gesagt das Struct nicht das Gleiche ist wie Array. Könntest du evtl. einen Beispiel Posten (bezogen auf mein Array) wie man so einen Struct aufbaut?

  • Hätte es so probiert, kann es ja aber leider nicht testen.

    Spoiler anzeigen
    [autoit]

    $Struct = DllStructCreate('char[2]')
    DllStructSetData($Struct, 1, "GROUP1")
    DllStructSetData($Struct, 2, "GROUP2")

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

    $objDll = DllOpen("SMSRsGen.dll")
    $intResult = DllCall($objDll, "int", "DDRAddStringArray", "str", "System Group Name", "ptr", DllStructGetPtr($Struct), "int", 2, "int", 64, "dword", 16)
    DllClose($objDll)

    [/autoit]
  • Moin,

    ich kann es ebensowenig testen, aber es sollte in etwa so aussehen:

    Spoiler anzeigen
    [autoit]

    ;
    Global Const $ADDPROP_KEY = 0x00000008

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

    Global Const $SMSRsGendll = DllOpen("SMSRsGen.dll")
    ; For SMS 2003, this value cannot be greater than 900 characters.
    ; For SMS 2.0, this value cannot be greater than 255 characters.

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

    $MAX_STRING = 255 ; hier die max. Stringlänge

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

    $sGroupName = "System Group Name"

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

    Global $arrGroups = DllStructCreate ("char ["&$MAX_STRING&"];"& _
    "char ["&$MAX_STRING&"];")

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

    DllStructSetData ($arrGroups, 1, "GROUP1")
    DllStructSetData ($arrGroups, 2, "GROUP2")

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

    If (not DDRAddStringArray ( _
    $sGroupName, _
    DllStructGetPtr ($arrGroups), _
    2, _
    $MAX_STRING, $ADDPROP_KEY) ) Then

    ConsoleWrite ("!> DDRAddStringArray returns: S_FALSE" & @crlf)
    Else
    ConsoleWrite ("+> DDRAddStringArray returns: S_OK" & @crlf)
    EndIf

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

    DllClose($SMSRsGendll)

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

    Func DDRAddStringArray ($sName, $sArray, $nArraySize, $nSQLWidth, $dwFlags)

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

    Local $aRes = DllCall($SMSRsGendll, "int", "DDRAddStringArray", _
    "str", $sName, _
    "ptr", $sArray, _
    "int", $nArraySize, _
    "int", $nSQLWidth, _
    "dword", $dwFlags)
    Return $aRes[0]

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

    EndFunc
    ;

    [/autoit]


    EDIT: Sorry, habe mal wieder die Hälfte vergessen, Beitrag ist korrigiert !


    Gruß
    Greenhorn


    3 Mal editiert, zuletzt von Greenhorn (3. September 2009 um 20:13)

  • Hallo Greenhorn
    habe deinen Code getestet. Vielen Dank noch mal. Damin komme ich auf jeden fall weiter als mit meiner Version. Leider funktioniert es noch nicht ganz. Vielleicht kannst du mich noch mal unterstützen.
    Ich habe deinen Code wie folgt erweitert:

    [autoit]


    Global Const $ADDPROP_NONE = 0x00000000
    Global Const $ADDPROP_GUID = 0x00000002
    Global Const $ADDPROP_KEY = 0x00000008
    Global Const $ADDPROP_ARRAY = 0x00000010
    Global Const $ADDPROP_NAME = 0x00000044
    Global Const $MAX_STRING = 255 ; hier die max. Stringlänge
    ; For SMS 2003, this value cannot be greater than 900 characters.
    ; For SMS 2.0, this value cannot be greater than 255 characters.

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

    Global $strSite = "P01"
    Global $strComputer = "TESTPC"
    Global $strDdrFileName = "TEST.DDR"
    Global $strOS = "Windows XP Professional"
    Global $strDomainName = "TEST.LOCAL"

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

    Global $arrGroups = DllStructCreate ("char [" & $MAX_STRING & "];" & _
    "char [" & $MAX_STRING & "];")

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

    DllStructSetData ($arrGroups, 1, "GROUP1")
    DllStructSetData ($arrGroups, 2, "GROUP2")

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

    Global $arrOUs = DllStructCreate ("char [" & $MAX_STRING & "];" & _
    "char [" & $MAX_STRING & "];")

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

    DllStructSetData ($arrOUs, 1, "OU1")
    DllStructSetData ($arrOUs, 2, "OU2")

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

    Global $arrContainer = DllStructCreate ("char [" & $MAX_STRING & "];")

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

    DllStructSetData ($arrContainer, 1, "")

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

    Global $SMSRsGendll = DllOpen("SMSRsGen.dll")
    DDRNew("System", "SMS_AD_SYSTEM_GROUP_DISCOVERY_AGENT", $strSite)
    DDRAddString("Netbios Name", $strComputer, 64, $ADDPROP_KEY)
    DDRAddString("Operating System Name and Version", $strOS, 64, $ADDPROP_KEY)
    DDRAddString("Resource Domain OR Workgroup", $strDomainName, 64, $ADDPROP_KEY)
    DDRAddStringArray("System Group Name", DllStructGetPtr ($arrGroups), 2, $MAX_STRING, $ADDPROP_ARRAY)
    DDRAddStringArray("System OU Name", DllStructGetPtr ($arrOUs), 2, $MAX_STRING, $ADDPROP_ARRAY)
    DDRAddStringArray("System Container Name", DllStructGetPtr ($arrContainer), 1, $MAX_STRING, $ADDPROP_ARRAY)
    DDRWrite($strDdrFileName)
    DllClose($SMSRsGendll)

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

    Func DDRNew ($sArchitecture, $sAgentName, $sSiteCode)
    Local $aRes = DllCall($SMSRsGendll, "int", "DDRNew", _
    "str", $sArchitecture, _
    "str", $sAgentName, _
    "str", $sSiteCode)
    Return $aRes[0]
    EndFunc

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

    Func DDRAddStringArray ($sName, $sArray, $nArraySize, $nSQLWidth, $dwFlags)
    Local $aRes = DllCall($SMSRsGendll, "int", "DDRAddStringArray", _
    "str", $sName, _
    "ptr", $sArray, _
    "int", $nArraySize, _
    "int", $nSQLWidth, _
    "dword", $dwFlags)
    Return $aRes[0]
    EndFunc

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

    Func DDRAddString ($sName, $sValue, $nSQLWidth, $dwFlags)
    Local $aRes = DllCall($SMSRsGendll, "int", "DDRAddString", _
    "str", $sName, _
    "str", $sValue, _
    "int", $nSQLWidth, _
    "dword", $dwFlags)
    Return $aRes[0]
    EndFunc

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

    Func DDRWrite ($sFileName)
    Local $aRes = DllCall($SMSRsGendll, "int", "DDRWrite", _
    "str", $sFileName)
    Return $aRes[0]
    EndFunc

    [/autoit]

    Damit kann ich schon mal eine TEST.DDR Datei erzeugen (liegt bei unbenannt in TEST.TXT)
    Allerdings sind die Array Werte leer
    <16><System Group Name><11><255>
    BEGIN_ARRAY_VALUES
    <>
    <>
    END_ARRAY_VALUES
    END_PROPERTY
    BEGIN_PROPERTY
    <16><System OU Name><11><255>
    BEGIN_ARRAY_VALUES
    <>
    <>
    END_ARRAY_VALUES
    END_PROPERTY

    In den beiden ersten <> müsste GROUP1 und GROUP2 und in den zweiten <> dann OU1 und OU2

    Für den Test habe ich die SMSRsGen.dll aus dem SCCM 2007 SDK 4.0 verwendet (liegt bei)
    Hoffe ich habe nichts vergessen.
    Vielen Dank.

    autoit.de/wcf/attachment/5965/
    autoit.de/wcf/attachment/5966/

  • Gibt es vielleicht eine Möglichkeit anstatt einen Pointer auf einen Struct einen Pointer auf einen Array zu übergeben?
    ?(
    Ich habe gestern damit noch rumgespielt aber keine Möglichkeit gefunden einen Pointer von einem Array zu ermitteln.
    Sowas wie GetPtr($Array[]) gibt es in AutoIt nicht oder ich habs zumindest nicht gefunden.

    Gruß
    Edmann

    • Offizieller Beitrag

    Hallo,

    Arrays werden so erzeugt!

    Spoiler anzeigen
    [autoit]

    Global Const $ADDPROP_NONE = 0x00000000
    Global Const $ADDPROP_GUID = 0x00000002
    Global Const $ADDPROP_KEY = 0x00000008
    Global Const $ADDPROP_ARRAY = 0x00000010
    Global Const $ADDPROP_NAME = 0x00000044
    Global Const $MAX_STRING = 255 ; hier die max. Stringlänge
    ; For SMS 2003, this value cannot be greater than 900 characters.
    ; For SMS 2.0, this value cannot be greater than 255 characters.

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

    FileDelete("TEST.DDR")

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

    Global $strSite = "P01"
    Global $strComputer = "TESTPC"
    Global $strDdrFileName = "TEST.DDR"
    Global $strOS = "Windows XP Professional"
    Global $strDomainName = "TEST.LOCAL"

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

    Global $arrGroups = DllStructCreate ("ptr[2];char [" & $MAX_STRING & "];" & _
    "char [" & $MAX_STRING & "];")

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

    DllStructSetData($arrGroups, 1, DllStructGetPtr($arrGroups, 2), 1)
    DllStructSetData($arrGroups, 1, DllStructGetPtr($arrGroups, 3), 2)
    DllStructSetData ($arrGroups, 2, "GROUP1")
    DllStructSetData ($arrGroups, 3, "GROUP2")

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

    Global $arrOUs = DllStructCreate ("ptr[2];char [" & $MAX_STRING & "];" & _
    "char [" & $MAX_STRING & "];")

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

    DllStructSetData($arrOUs, 1, DllStructGetPtr($arrOUs, 2), 1)
    DllStructSetData($arrOUs, 1, DllStructGetPtr($arrOUs, 3), 2)
    DllStructSetData ($arrOUs, 2, "OU1")
    DllStructSetData ($arrOUs, 3, "OU2")

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

    Global $arrContainer = DllStructCreate ("ptr[1];char [" & $MAX_STRING & "];")

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

    DllStructSetData($arrContainer, 1, DllStructGetPtr($arrContainer, 2), 1)
    DllStructSetData ($arrContainer, 2, "")

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

    Global $SMSRsGendll = DllOpen("SMSRsGen.dll")
    DDRNew("System", "SMS_AD_SYSTEM_GROUP_DISCOVERY_AGENT", $strSite)
    DDRAddString("Netbios Name", $strComputer, 64, $ADDPROP_KEY)
    DDRAddString("Operating System Name and Version", $strOS, 64, $ADDPROP_KEY)
    DDRAddString("Resource Domain OR Workgroup", $strDomainName, 64, $ADDPROP_KEY)
    DDRAddStringArray("System Group Name", DllStructGetPtr($arrGroups, 1), 2, $MAX_STRING, $ADDPROP_ARRAY)
    DDRAddStringArray("System OU Name", DllStructGetPtr($arrOUs, 1), 2, $MAX_STRING, $ADDPROP_ARRAY)
    DDRAddStringArray("System Container Name", DllStructGetPtr($arrContainer, 1), 1, $MAX_STRING, $ADDPROP_ARRAY)
    DDRWrite($strDdrFileName)
    DllClose($SMSRsGendll)

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

    Func DDRNew ($sArchitecture, $sAgentName, $sSiteCode)
    Local $aRes = DllCall($SMSRsGendll, "int", "DDRNew", _
    "str", $sArchitecture, _
    "str", $sAgentName, _
    "str", $sSiteCode)
    Return $aRes[0]
    EndFunc

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

    Func DDRAddStringArray ($sName, $sArray, $nArraySize, $nSQLWidth, $dwFlags)
    Local $aRes = DllCall($SMSRsGendll, "int", "DDRAddStringArray", _
    "str", $sName, _
    "ptr", $sArray, _
    "int", $nArraySize, _
    "int", $nSQLWidth, _
    "dword", $dwFlags)
    Return $aRes[0]
    EndFunc

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

    Func DDRAddString ($sName, $sValue, $nSQLWidth, $dwFlags)
    Local $aRes = DllCall($SMSRsGendll, "int", "DDRAddString", _
    "str", $sName, _
    "str", $sValue, _
    "int", $nSQLWidth, _
    "dword", $dwFlags)
    Return $aRes[0]
    EndFunc

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

    Func DDRWrite ($sFileName)
    Local $aRes = DllCall($SMSRsGendll, "int", "DDRWrite", _
    "str", $sFileName)
    Return $aRes[0]
    EndFunc

    [/autoit]