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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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 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.Ima geFormat.B mp);
stream.Seek(0,SeekOrigin.B egin);
stream.Write(src,0,stream. Size);
Marshal.Copy(src,0,ptr,src .Length);
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.Ima
stream.Seek(0,SeekOrigin.B
stream.Write(src,0,stream.
Marshal.Copy(src,0,ptr,src
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.B egin);
Bitmap bmp = new Bitmap(stream);
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.B
Bitmap bmp = new Bitmap(stream);
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
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(hBitmap Handle);
resultHBitMap = myBitMap.GetHbitmap();
//pass resultHBitMap to unmanaged code
-------------------------- ---------- ---------- ---------- ---------- ---------- --
regards
prakash
--------------------------
IntPtr hBitmapHandle, resultHBitMap;
// hBitmapHandle get the hbitmap from the unmanaged code
Bitmap myBitMap = Bitmap.FromHbitmap(hBitmap
resultHBitMap = myBitMap.GetHbitmap();
//pass resultHBitMap to unmanaged code
--------------------------
regards
prakash
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.
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.
ASKER
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