c# - Safety of passing HBITMAP handle from unmanaged to managed code for created a System.Drawing.Bitmap -
I'm very new to managed / unmanaged interop, so I'm looking to get some feedback about the following opinion To get a bitmap from unmanaged C ++ to manage, the # is the basic idea:
- C # call an interop function,
FetchImage , which is unmanaged C In ++, it passes anout int paramfetchImage is related tolong * param.- In C ++,
FetchImage creates aCBitmap somewhere safe, that is not local, does some draws on it, bitmap'sHBITMAP usesHandleToLong () to convertlong to handle , stores it the ultimate for C #, and returns.- Back in C #, the
outside int param is converted toIntPtr anduses the system to copy the data Drawing.Image.FromHbitmap to create andSystem.Drawing.Bitmap objects.- C # then calls another interop function,
ReleaseImage .- The resources associated with the C ++,
release image in theCBITMAP have already been created.This is the abstract for impatient more specific code examples given below.
C + interface definitions for functions:
namespace {std :: unique_ptr & lt; Cmtmap> Small; } HRESULT __stdcall Assistant: FetchImage (/ * [out] * / long * hBitmap) {bitty.reset (new CBitmap); // Call CreateBitmap and then draw something, // Make sure that it is not selected in DC when * hBitmap = HandleToLong (bitty-> GetSafeHandle ()); Return S_OK; } HRESULT __stdcall helper :: Release Image {bitty.reset (); Return S_OK; }IDL prototype for interop functions, which are wrapped in the support group in C #:
[ID (1)] HRESULT FetchImage (Long * HBitmap); [Id (2)] HRESULT release image (); In the affiliate category, these C # prototypes produce:
zero FetchImage (out int hibitmap); Zero release image ();and C # who calls them looks like this:
int ret; Assistant. Fat image (outright); Bitmap b = image. FRHMP (IntPtr) ret Helper.ReleaseImage (); / is a case of calling or. If the release image is getting things out of sync somewhere else then maybe I will have a list ofCBITmap instead of just one, then return the handle back torelease image Send it on so that it only destroys one by matching. > FetchImage Call.Do not I have any information? I have to do this work, I just wanted to make sure that I am not doing anything dangerous because I do not know any better. You can only declare that it is the responsibility of releasing HBITMAP. Since this simplifies your C ++ code, you can remove the ReleaseImage method. Example:
HRESULT __stdcall Assistant: FetchImage (/ * [out] * / HBITMAP * hBitmap) {* hBitmap = NULL; // Failure Exact_text & lt; Cgi.tap & gt; BMP (new CBITmap); // CreateBitmap call and then draw something, // Make sure that it is not selected in DC when * hBitmap = (HBITMAP) bmp- & gt; Apart (); Return S_OK; } // Delete the release image and delete all global variables ... // C # Example: IntPtr ret; Assistant. Fat image (outright); Try {bitmap b = image. FHMHMHMMMP (RT); } Finally {DeleteObject (ret); // Call in PinoWoK GDI}Alternatively, you can check back using. Here are some benefits:
- The caller frees the returned image using the standard COM reference calculation. Usually, the caller is free from being concerned about releasing the returned image (unless the caller is another C ++ program that requires manual callIUnknown :: Release).
- Better compatibility with other COM-enabled languages, such as VBA / VB6 The iCutcher is the standard way of passing around a photo in COM.
- In C ++,
Comments
Post a Comment