GDI+ Bitmap aus DLL zurück an Autoit zurückgeben wie GDI+ selber

  • So ich weiß nebenan ist ein fast gleicher Thread, aber ich habe nur eine kurze Frage, die sich nicht auf das Objekthandling in Autoit bezieht:
    Ich würde gerne wie die gdiplus.dll selber, eine Bitmap als Parameter in der DLL aufnehmen, bearbeiten und eine neue Bitmap zurückgeben.
    Was muss ich für Sachen Angeben damit

    [autoit]

    $ret=Dllcall(".dll","none","func","handle",$oldbmp,"ptr*","")
    $newbmp=$ret[2]

    [/autoit]


    klappt.
    Ich hab in C++ im Moment Bitmap* Func(Bitmap*,bool), das Bitmap* als rückgabetyp scheint schonmal falsch zu sein

    PS: Muss ich in der DLL noch extra GDI+ Startup aufrufen?

    Einmal editiert, zuletzt von TheShadowAE (20. Oktober 2010 um 11:07)

  • Hi,
    es kommt natürlich drauf an, was du überhaupt an "deinedll.dll" übergeben möchtest.
    Mal angenommen, du hast aus einer GDI-Funktion in autoIt ein HBITMAP erhalten, dann sollte der Call so aussehen:

    [autoit]

    $HBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap(blahblah) ;diese Variable, NICHT DEn POINTER, würde ich an die dll übergeben

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

    $ret = DllCall("deinedll.dll", "handle", _ ;abhängig davon, was deine dll-funktion zurückgibt, ggf auch ein fehlercode...dann z.b. int(fehlernummer) oder bool
    , "FunktionsNameInDerDll", _ ;dein c++-funktionsname
    , "ptr", _ ;handle oder pointer, der von der AutoItfunktion zurückgegeben wurde, dword geht auch....
    , $HBITMAP) ;variable, in der die Rückgabe der AutoItfunktion steht

    ;"ptr*" verwenden, wenn du in der dll den pointer auf die VARIABLE mit dem Inhalt HBITMAP auswerten willst

    [/autoit]
    Zitat

    Muss ich in der DLL noch extra GDI+ Startup aufrufen?

    nein

  • Da fragste mal wieder den richtigen^^, aber wieso willst du Pointer übergeben?

    Zitat

    aber eigentlich suche ich nach GDI+ Bitmapübergabe

    erklär das mal genauer....in AutoIt bekommst du $IRGENDWAS als Rückgabe einer _GDIplus_schlagmichtot()-Funktion.
    Oder willst du den Pointer auf die BitmapDATEN = Pixeldata AARRGGBB übergeben?
    Das ist erstmal schnurz und piepe. Der Datentyp (z.B. INT) ist nur dazu da die Anzahl und ggf auch die Ausleserichtung der an die Dll-funktion zu übergebenden Bytes festzulegen.
    Der Asterix * ist nur dazu da, statt den WERT den Zeiger (Pointer) auf die Speicherstelle des Wertes zu übergeben.
    In Assembler z.B.
    VAR db 7
    erstellt an der Speicherstelle 0x00234567 ein dword mit dem Inhalt 00 00 00 07
    ein mov eax, VAR würde 0x00234567 in eax schreiben, entsprechend *VAR in C++ (der pointer auf die variable)
    aber mov eax,[VAR] würde 00 00 00 07 ins eax schreiben, entsprechend VAR in C++ (der inhalt der variable)

    Also kommts nur drauf an, sich zu einigen zwischen AutoIt-Dllcall und C++ Funktion in der Dll
    WAS du letztendlich übergibst ist völlig schnurz, wichtig ist nur, dass der Empfänger (die dll-func) weiss, was der Sender (AutoIt) abgeschickt hat!

    Zeig doch mal die ersten 5 Zeilen deiner dll-Funktion in C++, so dass man sehen kann was dort überhaupt angefordert wird

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    2 Mal editiert, zuletzt von Andy (20. Oktober 2010 um 21:21)

  • Ich will es ja wie in der Gdiplus.dll behandeln, weil dort eine neue Bitmap erstellt wird, die aus Autoit dann wieder von GDI+ gelöscht werden soll. Meine Func macht also nichts anderes außer mit
    "Bitmap* neuebitmap=new Bitmap(width,height,pixelformat);"
    eine neue Bitmap zu erstellen (mit new glaube ich auf dem Stack oder Heap) und die wieder an Autoit zurück gibt nach ein paar Veränderungen

  • ok, dann reicht eine ganz normale "Variable" im AutoIt-dllcall.
    mach mal das * hinter Bitmap weg, dann musst du in AutoIt den Pointer nicht auswerten (dazu müsstest du eine struct erstellen an der Position des Pointers und dort den Wert BITMAP auslesen)

    also wäre der call

    [autoit]

    $HBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap(blahblah) ;diese Variable, NICHT DEn POINTER, würde ich an die dll übergeben

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

    $ret = DllCall("deinedll.dll", "ptr", _ ;handle oder pointer ist egal, dieselbe "datenstruktur"
    , "FunktionsNameInDerDll", _ ;dein c++-funktionsname
    , "ptr", _ ;handle oder pointer, der von der AutoItfunktion zurückgegeben wurde, dword geht auch....
    , $HBITMAP) ;variable, in der die Rückgabe der AutoItfunktion steht

    $HBITMAP=$ret[0] ;die rückgabe aus der Dll einer AutoIt-variablen zuweisen

    [/autoit]
  • wenn du vor dem dllcall die bitmap noch garnicht hast, sondern erst in der dll erstellt, brauchst du natürlich auch keinen Parameter an die dll zu übergeben!
    Dein Parameter neuebitmap ist dann der Rückgabeparameter!

    [autoit]

    $ret = DllCall("deinedll.dll", "handle", _ ;handle oder pointer ist egal, dieselbe "datenstruktur"
    , "FunktionsNameInDerDll") ;dein c++-funktionsname

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

    $HBITMAP = $ret[0] ;die rückgabe aus der Dll einer AutoIt-variablen zuweisen

    [/autoit]
  • hi, nochmal für mich zum mitschreiben:
    Welche Variablen/Parameter brauchst du IN der Dll, die von AutoIt übergeben werden müssen?
    bsp:
    AutoIt dllcall (hoehe,breite) ===> dllfunc bitmap(hoehe,breite)

    und gibt die Dll-Funktion einen Wert an AutoIt zurück? welchen?

  • Ich übergebe eine Bitmap* und kriege auch eine zurück:

    Spoiler anzeigen
    Spoiler anzeigen
    [autoit]

    Func _BetterBitmap($bmp,$deleold=True)
    Local $nbmp
    Local $ret=DllCall(@ScriptDir&"\BetterBitmap.dll","ptr*","BContrast","ptr*",$bmp,"bool",$deleold)
    $nbmp=$ret[0]
    $ret=DllCall(@ScriptDir&"\BetterBitmap.dll","ptr*","BFehler","handle",$nbmp)
    $nbmp=$ret[0]
    Return $nbmp
    EndFunc

    [/autoit]


    So sieht es im Moment aus. Leider stürzt es an der kommentierten Stelle ab!

  • Hi,
    autoIt nimmt standardmässig den stdcall an, wenn du cdecl verwendest, dann musst du das im Dll-Aufruf mitteilen

    [autoit]

    Func _BetterBitmap($bmp,$deleold=True)
    Local $nbmp
    Local $ret=DllCall(@ScriptDir&"\BetterBitmap.dll","ptr*:cdecl","BContrast","ptr*",$bmp,"bool",$deleold)
    $nbmp=$ret[0]
    $ret=DllCall(@ScriptDir&"\BetterBitmap.dll","ptr*:cdecl","BFehler","handle",$nbmp)
    $nbmp=$ret[0]
    Return $nbmp
    EndFunc

    [/autoit]
  • entweder im c++ ändern oder im autoitcall^^