Jump to content

MemoryFuncCall [Solved]


Recommended Posts

In the standard UDF GuiRichEdit.au3, resides a line of code

Call("MemoryFuncCall" & "", "long", $lpReleaseFunc, "ptr", $lpLockBytes)

Line 5713 to be precise.

Can anyone tell me where this function is? As it does not seem to be in that UDF.

My goal is to get rid of it somehow, or just call the function in a normal fashion.

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Link to comment
Share on other sites

That should be converted to DLLCallAddress.

DllCallAddress("long", $lpReleaseFunc, "ptr", $lpLockBytes)

When I wrote this part, DLLCallAddress was still missing. The UDF did not force a custom COM-object on each RichEdit, so I did not want to force this dependency on all users regardless of their usage of the COM-object for image display. Still, I wanted to include the possibility for a proper memory management without leaks.

Edit: Antoher way should be this (trancexx discovered it while writing AutoItObject):

If $sc Then ; Call IUnknown->Release on $lpLockBytes
        Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
        Local $aCall = DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $lpLockBytes, "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))
    EndIf
Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

I have svn access, you want me to change it? It doesn't change any functionality, correct?

It actually fixes memory leaks. But before changing, confirm that it is working (Drag&Drop an image in an AutoIt-Richedit, minimize and restore the window, check the image is still there)

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Only reason I was looking at it is I dont like warnings in scite.

And Call() produces one if using obfuscator. It certainly has not affected my script, but I'm not using any images in it.

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Link to comment
Share on other sites

Pretend I've never used the RichEdit UDF before. How would I test that properly? Any of the examples is enough?

Should be. I'll reboot to windows and test it ;) The modification is working fine. (Remove the variable $aCall if you want to avoid an unused-warning if you use the alternative fix) Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Should be. I'll reboot to windows and test it ;) The modification is working fine. (Remove the variable $aCall if you want to avoid an unused-warning if you use the alternative fix)

I missed your edit. The DllCallAddress() version looks neater to me. What do you think?

Do I commit this?

If $sc Then
  Local $obj = DllStructCreate("ptr", $lpLockBytes)
  Local $iUnknownFuncTable = DllStructCreate("ptr[3]", DllStructGetData($obj, 1))
  Local $lpReleaseFunc = DllStructGetData($iUnknownFuncTable, 3)
  DllCallAddress("long", $lpReleaseFunc, "ptr", $lpLockBytes)
  If @error = 1 Then ConsoleWrite("!> Needs MemoryDLL.au3 for correct release of ILockBytes" & @CRLF)
EndIf
Edited by AdmiralAlkex
Link to comment
Share on other sites

I tested both variants, for me they work fine.

@JohnOne: The function is not broken, but there is a memory leak when adding Images from Clipboard or DragDrop ;)

If $sc Then ; Call IUnknown->Release on $lpLockBytes
  Local $obj = DllStructCreate("ptr", $lpLockBytes) ; prepare access to vTable
  Local $iUnknownFuncTable = DllStructCreate("ptr[3]", DllStructGetData($obj, 1)) ; access IUnknown vTable
  Local $lpReleaseFunc = DllStructGetData($iUnknownFuncTable, 3) ; get address of IUnknwon->Release
  DllCallAddress("long", $lpReleaseFunc, "ptr", $lpLockBytes) ; call release
EndIf

OR

If $sc Then ; Call IUnknown->Release on $lpLockBytes
        Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr") ; prepare variant for return value
        ; call 3rd function (offset: 2 pointers) in vTable of lpLockBytes (IUnknown->Release) as stdcall
        ; assumes 4 byte pointer size for 32bit (x86),
        ; 8 byte pointer size for 64bit (x64)
        DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $lpLockBytes, "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))
    EndIf
Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

I tested both variants, for me they work fine.

@JohnOne: The function is not broken, but there is a memory leak when adding Images from Clipboard or DragDrop :)

You keep saying OR ;)

I went ahead and commited the first version. Feel free to PM if there's anything else, we are reaching the limits of what could be called "on topic", and JohnOne looks sleepy.

If $sc Then ; Call IUnknown->Release on $lpLockBytes
  Local $obj = DllStructCreate("ptr", $lpLockBytes) ; prepare access to vTable
  Local $iUnknownFuncTable = DllStructCreate("ptr[3]", DllStructGetData($obj, 1)) ; access IUnknown vTable
  Local $lpReleaseFunc = DllStructGetData($iUnknownFuncTable, 3) ; get address of IUnknwon->Release
  DllCallAddress("long", $lpReleaseFunc, "ptr", $lpLockBytes) ; call release
EndIf

OR

Link to comment
Share on other sites

You keep saying OR ;)

Don't force me to a decision when I'm tired :) I like the DLLCallAddress, too. It is easier to understand than DispCallFunc.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

I totally forgot about that one. We have too many ways to achieve the goal now ;)

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Don't force me to a decision when I'm tired :) I like the DLLCallAddress, too. It is easier to understand than DispCallFunc.

lol, like I wasn't tired at 5 in the morning ;)
Link to comment
Share on other sites

But why aren't you using ObjCreateInterface()? It's made for that.

Local Const $sIID_ILockBytes = "{0000000A-0000-0000-C000-000000000046}"
Local $oLockBytes = ObjCreateInterface($that_pointer, $sIID_ILockBytes, "")
;... Whatever here
$oLockBytes.Release()

I would do that.

You should get someone to look at that then.
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...