C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 02-08-2010, 02:26 AM   #1
Registered User
 
Join Date: Feb 2010
Posts: 2
changing protected memory

Hi

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   Reply With Quote
Old 02-08-2010, 05:55 AM   #2
Registered User
 
kryptkat's Avatar
 
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   Reply With Quote
Old 02-08-2010, 10:49 PM   #3
Unregistered User
 
Yarin's Avatar
 
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   Reply With Quote
Old 02-08-2010, 11:22 PM   #4
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 8,322
Quote:
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.
IDisposable is just one of a few major flaws in the design of C# and only serves to act as a destructor. In C# you cannot directly call a finalizer from any code which means you can never force an object to do a task when it is destroyed. You can get around this by implementing IDisposable with one catch. Other objects and .NET do not know if an object is disposable or not and object.dispose() is not the same thing. So in order to effectively use IDisposable you essentially must query the object to see if it is an IDisposable and act accordingly if it is. Really ignorant design if you ask me.

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   Reply With Quote
Old 02-09-2010, 05:36 AM   #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;
        }
my C++:
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;
        }
Anytime I try to do something with bitmap from buffer I get access violation. Not mentioning that BufferCB in c++ returns BYTE *pBuffer which I found impossible to translate to IntPtr (needed for creation of bitmap) so instead Im using :

Code:
   BensBitmaps bensbmp;
   test.pSampleGrabber->GetCurrentBuffer(&(test.cbBuffer), (long*)test.pBuffer);
   bensbmp.BHmakeBitmap3(test.MediaType,test.pBuffer,NULL);
while using BufferCB only as indicator that buffer is ready.

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   Reply With Quote
Old 02-09-2010, 08:51 AM   #6
Registered User
 
kryptkat's Avatar
 
Join Date: Dec 2002
Posts: 518
nakenski slang for nak negative acknowledge aka no can do. meow.
kryptkat is offline   Reply With Quote
Old 02-09-2010, 07:03 PM   #7
Super Moderator
 
Bubba's Avatar
 
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   Reply With Quote
Old 02-09-2010, 07:06 PM   #8
Registered User
 
jeffcobb's Avatar
 
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...
__________________
C/C++ Environment: GNU CC/Emacs
Make system: CMake
Debuggers: Valgrind/GDB
jeffcobb is offline   Reply With Quote
Old 02-09-2010, 07:38 PM   #9
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 8,322
Quote:
I still don't understand why this code in c# works but similar doesn't in c++:
When you say C++ I'm assuming you mean managed C++ given your use of managed pointer types.

Code:
ISampleGrabberCB.BufferCB
Are you in the habit of putting dots in your function names or is this a board typo?

Quote:
Not mentioning that BufferCB in c++ returns BYTE *pBuffer which I found impossible to translate to IntPtr (needed for creation of bitmap) so instead Im using :
There are other .NET data types. I would recommend googling this and you will probably end up over at CodeGuru, Dev-X, or Experts Exchange. They all usually have very good info on mixing managed and unmanaged code.

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   Reply With Quote
Old 02-09-2010, 10:18 PM   #10
I have a hat!?
 
Join Date: Apr 2008
Posts: 194
Quote:
Not mentioning that BufferCB in c++ returns BYTE *pBuffer which I found impossible to translate to IntPtr (needed for creation of bitmap) so instead Im using :
You missed the obvious one then:
Code:
System::IntPtr ptr(pBuffer);
Quote:
Originally Posted by Bubba View Post
Code:
ISampleGrabberCB.BufferCB
Are you in the habit of putting dots in your function names or is this a board typo?
It's an explicit implementation of an interface.
adeyblue is offline   Reply With Quote
Old 02-09-2010, 11:24 PM   #11
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 8,322
Quote:
It's an explicit implementation of an interface.
Ah. Nice to know. Thanks for the link.
__________________
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   Reply With Quote
Reply

Tags
access, bmp, dxtext, violation

Thread Tools
Display Modes

Forum Jump

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


All times are GMT -6. The time now is 12:20 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22