0

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!!

Zharios
  • 183
  • 1
  • 18
  • 1
    Possible duplicate of [How can i free hbitmap](https://stackoverflow.com/questions/16944048/how-can-i-free-hbitmap) – ProgrammingLlama May 11 '18 at 08:01
  • no its a duplicated. In this post he need delete HBITMAP in C++ , in my case i can`t doing it. – Zharios May 11 '18 at 08:04
  • You need to delete it in C++? Not in C# like the answer to the question I linked? – ProgrammingLlama May 11 '18 at 08:06
  • Zharios can you clarify what you're asking for? Your question title says "Free HBITMAP from c++ in c#" – ProgrammingLlama May 11 '18 at 08:28
  • @john i check your Posible duplicate message and the problem is similar but not exact the same. I my case the HBITMAP is inside a Struct that i trabsform to a c# struct with ` Marshal.PtrToStructure`. I ttry aply the post solution with a IntPtr to struct and does nothing. – Zharios May 11 '18 at 08:33
  • 1
    You must use SendMessage(). And you need to release the HBITMAP when your code (or UI, presumably) no longer uses it. You did not tell us how you use it, a random guess is that you'll want to pinvoke DeleteObject in a FormClosed event handler. Also when you get another message. – Hans Passant May 11 '18 at 09:02
  • @HansPassant Thanks a lot!!! this was my problem. Please put the answer and i get your points. – Zharios May 11 '18 at 09:16
  • I'm just guessing, not enough info. Please use what you've learned to complete the Q+A you started. Post the solution and mark it as the answer. – Hans Passant May 11 '18 at 09:18

1 Answers1

1

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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770