I’m trying to get a System.Drawing.Image (generated in a .NET dll) into a picture control in a Visual C++/MFC application. I’m new to COM/Interop, but I have interop’ing working. However I’m not sure how to pass the bitmap data from C# to C++.
The basic process is:
1. C++/MFC calls on COM server (interop)
2. C# COM server calls .NET DLL
3. Generate System.Drawing.Image in .NET dll
4. C# COM server returns bitmap data in some form (interop)
5. C++/MFC displays bitmap
In the C# COM Server, I have:
Bitmap bm = new Bitmap(img);
IntPtr hbm = bm.GetHbitmap();
return hbm;
Where img is the System.Drawing.Image I want to send over. The method returns an IntPtr, which gets marshaled to a long*
In my MFC C++ Test application, I have:
long pOutHB;
pQRCodePtr->Generate(m_sQRText.AllocSysString(), 50, 50, &pOutHB);
HBITMAP hb = (HBITMAP) pOutHB;
m_QRCodePicture.SetBitmap(hb);
m_QRCodePicture.Invalidate();
m_QRCodePicture.UpdateData();
But nothing gets put in the picture control. I also tried creating a CBitmap using the HBITMAP, but that was unsuccessful as well. I have verified the .NET dll/COM server is generating a valid image.
Most of my research on this issue uncovered taking a C++ bitmap and making a System.Drawing.Image, not going the other direction (like this question:
Safety of passing HBITMAP handle from unmanaged to managed code for created a System.Drawing.Bitmap)
Am I going down the right path here? I realize that my code may be completely wrong. I’m looking for something to point me in the right direction here. My first try was to pass a byte[] array, but some reading pointed me in the direction of passing the HBitmap pointer as being more efficient.
For future reference, it turns out I was doing it correctly. The HBITMAP handle is valid and persists even after the return from the .NET function and pass through COM interop. According to MSDN, you need to cleanup the object.
Adding some cleanup, this works.
Generateis a call to the COM wrapper service which returns anIntPtrwhich is marshaled to along.