![]() |
| | #1 |
| Registered User Join Date: Feb 2010
Posts: 2
| changing protected memory I wanted to make application that is able to draw on video sent from usb webcam. To do that I tweaked code from directx sdk namely dxtext (example was done in c# so I converted it to c++). Problem is that my class to be able to perform operations on camera ready bitmap on each new frame need to inherit from ISampleGrabber for ISampleGrabberCB callback. But to perform any changes to protected memory it would have to inherit from IDisposable too, something that is not possible in C++ or I don't know how, because ISampleGrabber is unmanaged class and C++ forbids inheritance from both managed and unmanaged classes/interfaces. Changing all classes on ISampleGrabber side to managed is out of question. Is there a way I can change bitmap that is in protected memory from unmanaged code? |
| mathewmefiu is offline | |
| | #2 |
| Registered User Join Date: Dec 2002
Posts: 518
| nakenski that is why it is called protected memory. make a copy hdc and work with the copy. meow. |
| kryptkat is offline | |
| | #3 |
| Unregistered User Join Date: Jul 2007
Posts: 1,016
| nakenski?
__________________ "Those who would give up Essential Liberty to purchase a little Temporary Safety, deserve neither Liberty nor Safety." - Benjamin Franklin |
| Yarin is offline | |
| | #4 | |
| Super Moderator Join Date: Aug 2001
Posts: 8,322
| Quote:
In C++ you would simply provide a destructor to do the cleanup and it is a much simpler more defined process. Every time an object is destroyed you are guaranteed that the destructor for that object (even if you don't write one) will be called. If you wish to mix managed and unmanaged code then you need to use managed C++. If you create a ref class it can be seen and used by C#. The managed C++ then can wrap an unmanaged pointer inside of a managed interface which essentially amounts to a simple call through or proxy pattern. You can also call from C++ to C# using the reverse of this mechanism but there are a few more caveats in that you cannot have any managed objects inside of a unmanaged class which is to be used by C++. However one can avoid this by using interfaces. Then it is the underlying impl that actually does the heavy lifting. This allows for uniform conformance to an interface on both sides while also allowing seamless integration of managed and unmanaged code. The most important thing to remember when doing this type of programming is to use .NET data types in the interfaces. You will need to write conversion functions if you wish to convert std::string to System::String and vice versa. You also cannot use any STL containers inside of a ref class that is to be used by C#. You can, however, use generics in managed C++ which also appear as generics to C#. The managed C++ interface would then convert this generic into a C++ template and make the call to the C++. Managed C++ is really the best and worst of both worlds in that it can both talk to and use managed and unmanaged code. As such it makes it a great way to mix C# and C++ in the same project. There are many books about this and tons of online articles on how to do this properly. It is definitely worth your time and effort to research it. This type of programming and skill set is definitely in demand and will be in the future as other systems start to utilize the robustness of .NET but still need the raw speed of C/C++ for mission critical tasks. I work with this type of stuff each day and although it seems daunting at first once you get the hang of it - it becomes a very powerful tool.
__________________ I remember when The Weather Channel talked about weather, MTV played music videos, and the History Channel talked about history instead of conspiracy theories. Last edited by Bubba; 02-08-2010 at 11:29 PM. | |
| Bubba is offline | |
| | #5 |
| Registered User Join Date: Feb 2010
Posts: 2
| Why different? I still don't understand why this code in c# works but similar doesn't in c++: original c#: Code: int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen )
{
Graphics g;
String s;
float sLeft;
float sTop;
SizeF d;
g = Graphics.FromImage(bitmapOverlay);
g.Clear(System.Drawing.Color.Transparent);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// Prepare to put the specified string on the image
g.DrawRectangle(System.Drawing.Pens.Blue, 0, 0, m_videoWidth - 1, m_videoHeight - 1);
g.DrawRectangle(System.Drawing.Pens.Blue, 1, 1, m_videoWidth - 3, m_videoHeight - 3);
d = g.MeasureString(m_String, fontOverlay);
sLeft = (m_videoWidth - d.Width) / 2;
sTop = (m_videoHeight - d.Height ) / 2;
g.DrawString(m_String, fontOverlay, System.Drawing.Brushes.Red,
sLeft, sTop, System.Drawing.StringFormat.GenericTypographic);
// Add a frame number in the bottom right
s = "Frame " + m_Count.ToString();
d = g.MeasureString(s, transparentFont);
sLeft = (m_videoWidth - d.Width) - 10;
sTop = (m_videoHeight - d.Height ) - 10;
g.DrawString(s, transparentFont, transparentBrush, sLeft, sTop,
System.Drawing.StringFormat.GenericTypographic);
g.Dispose();
// need to flip the bitmap so it's the same orientation as the
// video buffer
bitmapOverlay.RotateFlip(RotateFlipType.RotateNoneFlipY);
// create and copy the video's buffer image to a bitmap
Bitmap v;
v = new Bitmap(m_videoWidth, m_videoHeight, m_stride,
PixelFormat.Format32bppArgb, pBuffer);
g = Graphics.FromImage(v);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// draw the overlay bitmap over the video's bitmap
g.DrawImage(bitmapOverlay, 0, 0, bitmapOverlay.Width, bitmapOverlay.Height);
// dispose of the various objects
g.Dispose();
v.Dispose();
// Increment frame number. Done this way, frame are zero indexed.
m_Count++;
return 0;
}
Code: HRESULT STDMETHODCALLTYPE Camera::BufferCB( double SampleTime, BYTE *pBuffer, long BufferLen )
{
Graphics^ g;
Bitmap^ bitmapOverlay = gcnew Bitmap(640, 480,
PixelFormat::Format24bppRgb);
g = g->FromImage(bitmapOverlay);
g->Clear(System::Drawing::Color::Transparent);
g->SmoothingMode = System::Drawing::Drawing2D::SmoothingMode::AntiAlias;
g->DrawRectangle(System::Drawing::Pens::Blue, 20, 20, 100, 100);
delete g;
bitmapOverlay->RotateFlip(RotateFlipType::RotateNoneFlipY);
Bitmap^ v;
BensBitmaps bensbmp;
// this is buffer form camera should not be different that whatever is returned by BufferCB I guess
test.pSampleGrabber->GetCurrentBuffer(&(test.cbBuffer), (long*)test.pBuffer);
bensbmp.BHmakeBitmap3(test.MediaType,test.pBuffer,NULL);
v = bensbmp.bmpN;
g = g->FromImage(v);
g->SmoothingMode = System::Drawing::Drawing2D::SmoothingMode::AntiAlias;
g->DrawImage(bitmapOverlay, 0 , 0, bitmapOverlay->Width, bitmapOverlay->Height); //<----- access violation
delete g;
delete v;
return 0;
}
Code: BensBitmaps bensbmp; test.pSampleGrabber->GetCurrentBuffer(&(test.cbBuffer), (long*)test.pBuffer); bensbmp.BHmakeBitmap3(test.MediaType,test.pBuffer,NULL); Am I right that reason why I can't access/change buffer is in my class not being managed original c#: internal class Capture : ISampleGrabberCB, IDisposable my c++: public class Camera : ISampleGrabberCB or am I just doing something wrong? Last edited by mathewmefiu; 02-09-2010 at 06:02 AM. |
| mathewmefiu is offline | |
| | #6 |
| Registered User Join Date: Dec 2002
Posts: 518
| nakenski slang for nak negative acknowledge aka no can do. meow. |
| kryptkat is offline | |
| | #7 |
| Super Moderator Join Date: Aug 2001
Posts: 8,322
| @kryptkat: If you do not have anything constructive to add to the thread please refrain from posting.
__________________ I remember when The Weather Channel talked about weather, MTV played music videos, and the History Channel talked about history instead of conspiracy theories. |
| Bubba is offline | |
| | #8 |
| Registered User Join Date: Dec 2009 Location: Henderson, NV
Posts: 887
| @Spoilsport: she was answering another question from earlier who did not understand her response. I didn't know what it meant either until she explained it just before your response...once she did I thought it was quite clever, truth be told... Easy now... |
| jeffcobb is offline | |
| | #9 | ||
| Super Moderator Join Date: Aug 2001
Posts: 8,322
| Quote:
Code: ISampleGrabberCB.BufferCB Quote:
I will look at my .NET book and let you know what I find. There is a way to convert that data type but I do not know what it is right off hand. You may also want to check what is provided to you by the marshalling object in C#.
__________________ I remember when The Weather Channel talked about weather, MTV played music videos, and the History Channel talked about history instead of conspiracy theories. | ||
| Bubba is offline | |
| | #10 | ||
| I have a hat!? Join Date: Apr 2008
Posts: 194
| Quote:
Code: System::IntPtr ptr(pBuffer); Quote:
| ||
| adeyblue is offline | |
| | #11 | |
| Super Moderator Join Date: Aug 2001
Posts: 8,322
| Quote:
__________________ I remember when The Weather Channel talked about weather, MTV played music videos, and the History Channel talked about history instead of conspiracy theories. | |
| Bubba is offline | |
![]() |
| Tags |
| access, bmp, dxtext, violation |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Suggestions on this C style code | Joelito | C Programming | 11 | 06-07-2007 03:22 AM |
| Relate memory allocation in struct->variable | Niara | C Programming | 4 | 03-23-2007 03:06 PM |
| Shared Memory - shmget questions | hendler | C Programming | 1 | 11-29-2005 02:15 AM |
| Memory is changing on me! | durban | C++ Programming | 8 | 10-13-2005 09:33 AM |
| Memory allocation and deallocation | Micko | C++ Programming | 3 | 08-19-2005 06:45 PM |