开发者

Memory leak if Bitmap get's raw data from Marshal.AllocHGlobal?

I am not clear on the mechanics of native int开发者_JS百科erop.

Suppose I do the following:

IntPtr nativeArray = Marshal.AllocHGlobal(stride * height);
someNativeCallToFillRawImageData(nativeArray, width, stride, height);
return new Bitmap(width, height, stride, PixelFormat.Format24bppRgb, nativeArray);

My allocated array then is the source of the bitmap (it works), but I am unsure if the memory for it will ever be cleared?

Alternatively, I can do the following (by changing DLLImport signature...native method is originally defined as (unsigned char *buff)):

byte[] managedArray = new byte[stride * height];
someNativeCallToFillRawImageData(managedArray, width, stride, height);
fixed (byte* ptr = managedArray)
{
   return new Bitmap(width, height, stride, PixelFormat.Format24bppRgb, new IntPtr(ptr));
}

which also works, but I am not clear on the difference exactly. I am also under the impression that the first variant is faster, due to it not having to cross managed/unmanaged boundiers.

Does a managed Bitmap object dispose of the data in Scan0, even though it was allocated by someone else? bitmap.Dispose() -> what happens to allocated memory in either managedArray or nativeArray ?

Thank you very much in advance!


If using Marshal.AllocHGlobal and the bitmap copies data from the pointer, you should free it with Marshal.FreeHGlobal. I advice you read MSDN on the BitMap constructor as to if it copies the data or just uses the pointer; if it just uses the pointer you have to wait with freeing it.


I don't think you need to allocate the memory yourself. Create an empty bitmap with the desired size, then call LockBits to access the raw pixel data:

Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
Rectangle rect = new Rectangle(width, height);
BitmapData data = null;
try
{
    data = bmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
    someNativeCallToFillRawImageData(data.Scan0, data.Width, data.Stride, data.Height);
}
finally
{
    if (data != null)
        bmp.UnlockBits(data);
}

This way, the memory is handled by the Bitmap object, so you don't need to worry about it.


You should create a Dispose method in a class which uses unmanaged resource (nativeArray in your case) and free it using Marshal.FreeHGlobal(nativeArray ). Something like this:

if(nativeArray != IntPtr.Zero)
    Marshal.FreeHGlobal(nativeArray);

You are responsible to call created Dispose method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜