Jump to content

CreateStreamOnHGlobal issue


Go to solution Solved by Yashied,

Recommended Posts

Posted (edited)

Hi,

I made an example named "IP Camera", basically you need to know that it converts binary data to bitmap using the recent _GDIPlus_BitmapCreateFromMemory function.

The script works fine for almost two hours. Then the _GDIPlus_BitmapCreateFromMemory is not able to convert the binary data (which is valid I checked it) to a bitmap and returns the error 2 which corresponds to the _WinAPI_CreateStreamOnHGlobal function.

I first tried to shutdown and restart the GDIPlus library because I didn't know the issue was from a WinAPI function (so it didn't work).

I'm wondering if it's possible that the function stops working after a huge number of calls? (does not make sense but I don't see what's wrong here).

Br, FireFox.

Edited by FireFox
Posted (edited)

@FireFox

You should release each stream object by using _WinAPI_ReleaseStream() function, otherwise you get a memory leak. Please carefully read the documentation.

P.S.

$hStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $hData, "int", True, "ptr*", 0)

Edited by Yashied
Posted

It is.

Here is the function:

;==================================================================================================================================
; Author ........: UEZ
; Modified.......: progandy
;===================================================================================================================================
Func _GDIPlus_BitmapCreateFromMemory($bImage, $hHBITMAP = False)
    If Not IsBinary($bImage) Then Return SetError(1, 0, 0)
    Local $aResult
    Local Const $memBitmap = Binary($bImage) ;load image saved in variable (memory) and convert it to binary
    Local Const $iLen = BinaryLen($memBitmap) ;get binary length of the image
    Local Const $GMEM_MOVEABLE = 0x0002
    $aResult = DllCall("kernel32.dll", "handle", "GlobalAlloc", "uint", $GMEM_MOVEABLE, "ulong_ptr", $iLen) ;allocates movable memory ($GMEM_MOVEABLE = 0x0002)
    If @error Then Return SetError(4, 0, 0)
    Local Const $hData = $aResult[0]
    $aResult = DllCall("kernel32.dll", "ptr", "GlobalLock", "handle", $hData)
    If @error Then Return SetError(5, 0, 0)
    Local Const $pData = $aResult[0] ;translate the handle into a pointer
    Local $tMem = DllStructCreate("byte[" & $iLen & "]", $pData) ;create struct
    DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
    DllCall("kernel32.dll", "bool", "GlobalUnlock", "handle", $hData) ;decrements the lock count associated with a memory object that was allocated with GMEM_MOVEABLE
    If @error Then Return SetError(6, 0, 0)
    Local Const $hStream = _WinAPI_CreateStreamOnHGlobal($pData) ;creates a stream object that uses an HGLOBAL memory handle to store the stream contents
    If @error Then Return SetError(2, 0, 0)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromStream($hStream) ;creates a Bitmap object based on an IStream COM interface
    If @error Then Return SetError(3, 0, 0)
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _
            "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "struct*", $tVARIANT) ;release memory from $hStream to avoid memory leak
    $tMem = 0
    $tVARIANT = 0
    If $hHBITMAP Then
        Local Const $hHBmp = __GDIPlus_BitmapCreateDIBFromBitmap($hBitmap) ;supports GDI transparent color format
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hHBmp
    EndIf
    Return $hBitmap
EndFunc   ;==>_GDIPlus_BitmapCreateFromMemory

 

And if you need the interesting part of the script:

$hBMP = _GDIPlus_BitmapCreateFromMemory($bStream)
 
;~ $hBMP = _GDIPlus_ScaleImage($hBMP, $x, $y)
 
$hBITMAP2 = __GDIPlus_BitmapCreateDIBFromBitmap($hBMP)
;~ $hBITMAP2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBMP)
 
_WinAPI_DeleteObject(_SendMessage($hPicCtrl, $STM_SETIMAGE, 0, $hBITMAP2))
 
_WinAPI_DeleteObject($hBITMAP2)
 
_GDIPlus_ImageDispose($hBMP)

Br, FireFox.

  • Solution
Posted (edited)
Posted

This is not necessary. Just check your script in Windows Task Manager for memory leak.

There wasn't any memory leak before.

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
×
×
  • Create New...