Link to home
Start Free TrialLog in
Avatar of Daeljan
Daeljan

asked on

Marshal / un Marshal Bitmaps


I need to pass .NET Bitmaps into a an unmanaged library dll, and retrieve them back.

How do a marshal a .NET bitmap to the unmanaged dll?

How do I obtain a .NET bitmap back from the unmanaged dll?

ASKER CERTIFIED SOLUTION
Avatar of 2266180
2266180
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Daeljan
Daeljan

ASKER

Have you actually tried this?

Can you show me some example code marshalling an unmarshalling a bitmap this way?
A bitmap structure in .NET is more then just image data, the same goes for GDI, so I don't readily see what you mean.

Thanks
Avatar of Daeljan

ASKER

Does a native GDI bitmap have exactly the same footprint as a .NET bitmap?
I ask because I will need to unpack the bytes in the unmanaged code into a GDI bitmap.
I don't have ready made code, but it's pretty straitforward (it's the "tehnique" I used for any data exchange that needs to have a specific format):
save the bitmap intro a memorystream
read up the byte[] data
copy it to the marshal pointer

code looks something similar to this:
            byte[] src;
            Bitmap bmp;
            MemoryStream stream = new MemoryStream();
            bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
            stream.Seek(0,SeekOrigin.Begin);
            stream.Write(src,0,stream.Size);
            Marshal.Copy(src,0,ptr,src.Length);

Avatar of Daeljan

ASKER

I've done similar marshalling in the past, but the thing is, how can this bitmap be reconstructed in the unmanaged c++ code - thats the other half of the problem.

ahh, I see the wisdom now, it's the same as saving to/ loading from a ram-disk! So the prototype for the image exchange would be

in C++:

void Func(unsigned char *pBitmapArray, int * pBitmapArrayLength);

and in C#:

void Func(IntPtr pBitmapArray, IntPtr pBitmapArrayLength);

The length is a pointer too because Func() may change the image, hence the size.

ok, so you call Func() in C# passing in an image to be changed somehow, how would you unmarshall the bytes back into a memory stream? I can handle the int ok, so just assume that we already have the length.

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
for the other half of the problem:
the bitmap is saved like into a file, but instead it's in memory. so basically what you do on the c++ side is open the bitmap from a file, but then again, you don't open it from a file, but from a memorystram. c++ should have such clasess/functions.

for the image exchange:
if the prototype is void Func(IntPtr pBitmapArray, IntPtr pBitmapArrayLength);
then my code changes to something like this:
                  byte[] dst;
                  int len = Marshal.ReadInt32(lenptr);
                  Marshal.Copy(ptr,dst,0,len);
                  MemoryStream stream = new MemoryStream();
                  stream.Write(dst,0,len);
                  stream.Seek(0,SeekOrigin.Begin);
                  Bitmap bmp = new Bitmap(stream);
Avatar of Daeljan

ASKER

Can someone please tell me if I can use a Bitmap object in unmanaged code?
The unmanaged code will link to a single threaded static library, hence I need to build it accordingly with the option:

C/C++ / Code Generation / Run Time Library / Single-threaded

I realise that this is a little off the thread but it is all part of the same problem, and before I test out the solution I need to be able to create the unmanaged dll.

I'm using VS 7.1 (2003). I created an MFC dll, but I cant seem to get access to these objects.

I'm really stuck in this one and I'm up against a deadline.

Many thanks
You can pass to unmanaged code plain data like int, string, array of pixels. Can you describe exactly what do you want to do in umnanaged code and why do you need to write unmanaged code?
Try this plz...
------------------------------------------------------------------------------

IntPtr hBitmapHandle, resultHBitMap;

// hBitmapHandle get the hbitmap from the unmanaged code
Bitmap myBitMap = Bitmap.FromHbitmap(hBitmapHandle);

resultHBitMap = myBitMap.GetHbitmap();

//pass resultHBitMap to unmanaged code
------------------------------------------------------------------------------

regards
prakash
Avatar of Daeljan

ASKER

Hi there,

I split the points on this one. My original solution was a multi-mode dll written in C++. Due to some instability in the application, I began to doubt that this dll was ok, hence the change of plan to Win32 (it was pure number crunching on bitmap pixels).

Anyhow, as it happens, another module somewhere in the app was violating memory and there was nothing wrong with the multi-mode dll, so I havent needed to try any of your solutions out. However, as they were informative enough, I have split the points.

Thanks.