CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Feb 2003
    Location
    Bangalore, India
    Posts
    1,354

    A little bit from C#

    Hi Guys,

    I was trying to understand some code in C# that's when I came across 'something' by the name of GCHandle and it shows it is from System.Runtime.InteropServices. Any idea of what these can be and any thing equivalent in VC++? I am interested in the Alloc member of GCHandle.

    To give some background info of what I am trying to do: I was experimenting with some sound libraries, the waveInxxx and the waveOutxxx to be precise, and I found out that there is some delay (about 1 sec) between the record and the playback. Tried many (documented) improvements with little success. Finally I stumbled upon a code in C# that does the same with minimum delay, and to my understanding (I might be wrong), the above shown constructs are the only kind of difference, where the allocation and usage of buffer is different. So I was thinking if I can have some information of what those are, I can have a better understanding of what should be done.

    Any comments are appreciated.
    Even if our suggestions didn't help, please post the answer once you find it. We took the effort to help you, please return it to others.

    * While posting code sections please use CODE tags
    * Please check the codeguru FAQ and do a little search to see if your question have been answered before.
    * Like a post, Rate The Post
    * I blog: Network programming, Bible

    I do all things thru CHRIST who strengthens me

  2. #2
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: A little bit from C#

    GCHandle is a wrapper to deliver the native pointer to managed memory. It 'pins' the memory, meaning that the GC can't move it, and delivers you an IntPtr containing its address.

    This is mainly used for interop with native code.

    ALWAYS FREE A GCHANDLE ! I.e. always call its Free() method after you've finished with it.

    It doesn't allocate memory.

    For instance have a look at the following example :

    Code:
    // C++ DLL Method
    void MyMethod(int *pnArray, int nCount)
    {
        for (int nIndex = 0; nIndex < nCount; nIndex += 1)
        {
            // do something
        }
    }
    
    // C# way of calling it
    using namespace System.Runtime.InteropServices;
    
    public class Example
    {
        [DllImport("MyMethod.dll")]
        static private extern void MyMethod(IntPtr array, int nCount);
    
        static public void MyMethod(int [] array, int count)
        {
            GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
            MyMethod(handle.AddrOfPinnedObject(), array.Length);
            handle.Free();
        }
    }
    You can do the same thing by enabling 'unsafe code' in the project settings and doing this :

    Code:
    public unsafe class Example
    {
        [DllImport("MyMethod.dll")]
        static private extern void MyMethod(int *array, int nCount);
    
        static public void MyMethod(int [] array, int count)
        {
            fixed (int *pArray = array)
            {
                MyMethod(pArray, nCount);
            }
        }
    }
    Darwen.
    Last edited by darwen; October 30th, 2006 at 03:27 AM.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  3. #3
    Join Date
    Feb 2003
    Location
    Bangalore, India
    Posts
    1,354

    Re: A little bit from C#

    Quote Originally Posted by darwen
    GCHandle is a wrapper to deliver the native pointer to managed memory.
    Thanks, that was what I was looking for. I am coding in VC++ and was trying to do the same thing in VC. Any comments about the efficiency?
    Even if our suggestions didn't help, please post the answer once you find it. We took the effort to help you, please return it to others.

    * While posting code sections please use CODE tags
    * Please check the codeguru FAQ and do a little search to see if your question have been answered before.
    * Like a post, Rate The Post
    * I blog: Network programming, Bible

    I do all things thru CHRIST who strengthens me

  4. #4
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: A little bit from C#

    Personally I've never had any speed problems with interop between C# and native dlls.

    However I've talked to other people who say things like "oh, it's really really slow !"

    Usually these people don't have an understanding of how interop works.

    For instance in my example above you could have equally have done this :

    Code:
    [DllImport("MyMethod.dll")]
    static private extern void MyMethod(int [] array, int nCount);
    Which is the way most people do it.

    The trouble with this is that the interop mechanism will create a native copy of the array to pass into the method, and then copy the values from this native array into the managed array after calling the method.

    So if the array is of a non-trivial size this will cause a serious performance hit.

    By using the IntPtr method you're pinning the array which means a pointer to the start of the memory block containing the array can be passed directly to the native code. Much, much faster.

    Darwen.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured