Thread: changing protected memory

  1. #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?

  2. #2
    Registered User kryptkat's Avatar
    Join Date
    Dec 2002
    Posts
    638
    nakenski that is why it is called protected memory. make a copy hdc and work with the copy. meow.

  3. #3
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    nakenski?

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    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.
    Last edited by VirtualAce; 02-08-2010 at 11:29 PM.

  5. #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.

  6. #6
    Registered User kryptkat's Avatar
    Join Date
    Dec 2002
    Posts
    638
    nakenski slang for nak negative acknowledge aka no can do. meow.

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    @kryptkat: If you do not have anything constructive to add to the thread please refrain from posting.

  8. #8
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    @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

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    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?

    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#.

  10. #10
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    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.

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    It's an explicit implementation of an interface.
    Ah. Nice to know. Thanks for the link.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Suggestions on this C style code
    By Joelito in forum C Programming
    Replies: 11
    Last Post: 06-07-2007, 03:22 AM
  2. Relate memory allocation in struct->variable
    By Niara in forum C Programming
    Replies: 4
    Last Post: 03-23-2007, 03:06 PM
  3. Shared Memory - shmget questions
    By hendler in forum C Programming
    Replies: 1
    Last Post: 11-29-2005, 02:15 AM
  4. Memory is changing on me!
    By durban in forum C++ Programming
    Replies: 8
    Last Post: 10-13-2005, 09:33 AM
  5. Memory allocation and deallocation
    By Micko in forum C++ Programming
    Replies: 3
    Last Post: 08-19-2005, 06:45 PM

Tags for this Thread