I have a memory problem caused by HBITMAP inside a struct sent from a callback by PostMessage
.
.
I have a c++ callback that send a struct to c# using PostMessage. This look like this:
HRESULT CALLBACK MyCallback(void* ref, HRESULT hr, LPCWSTR pszMessage) {
MyStruct st;
System::String^ serial = gcnew System::String(pszMessage);
serial = serial->Substring(0, serial->LastIndexOf("\\"));
serial = serial->Substring(serial->LastIndexOf("\\") + 1);
st.serial = StringToInt(serial);
HBITMAP send = updatePreview(pszMessage);
IntPtr ptr=(IntPtr) send;
st.imagen = ptr;
PostMessage(w, WM_UPDATE_PREVIEW, IMAGE_UPDATE, (LPARAM)&st);
}
This is my struct:
struct MyStruct
{
IntPtr imagen;
Int32 serial;
};
I receive this message in my c# code in my override WndProc:
protected override void WndProc(ref Message m)
{
if (m.Msg == AePhocus.AePhocusManager.WM_UPDATE_PREVIEW)
{
PICTURE_STRUCT imageinfo = new PICTURE_STRUCT();
Marshal.PtrToStructure(m.LParam, imageinfo);
....
....
}
}
This method refresh my previews and work fine but the problem is that i can't free the HBITMAP sent from c++. If i destroy the pointer after PostMessage them the image received is Null but if i don´t destroy it the use of memory increase with each preview.
Could someone help me with this problem please? Ty all!!
PostMessage()
is asynchronous. By the time the receiving WndProc
is called, the original MyStruct st
variable is already gone from memory, and the WndProc
is accessing garbage. You need to use SendMessage()
instead to ensure the struct stays alive until after the WndProc
exits.
As for freeing the HBITMAP
, the correct way is to use DeleteObject()
, assuming the HBITMAP
is not being passed across process boundaries.