Void pointer to managed object type

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • vijay.gandhi@gmail.com

    Void pointer to managed object type

    Hi,

    I am trying to convert some unmanaged code (C++) to managed code
    (using C++/CLI).

    1) One of the functions used returns a void* which I need to cast into
    a handle of a managed object. Can somebody please tell me how.

    Actually, the function that returns a void* is a part of a MFC class -
    CPtrList, used in my unmanaged code. I was searching of its equivalent
    in .NET, but couldn't find it. Is there any equivalent?

    2) Also, is there any equivalent of double pointers **, in .NET
    handles?

    Thanks in advance,
    Vijay.

  • vijay.gandhi@gmail.com

    #2
    Re: Void pointer to managed object type

    I received an answer in another forum:

    You can't cast a void* to unmanaged memory to a managed object
    reference. To turn this into managed memory, you'd have to use
    Marshal.Copy() or Marshal.PtrToSt ructure(). That will of course only
    work if you know the type of the data that the void* points to.

    To handle double pointers, you'd declare the member or function
    argument with the MarshalAs(Unman agedType.LPArra y) attribute. Or
    LPStruct if it points to a structure or LPTStr if it points to a
    string. In the case of an array, you'll also have to use the
    SizeConst argument to tell the marshaler how long the array is.

    Hans Passant.


    On May 19, 4:52 pm, "vijay.gan...@g mail.com" <vijay.gan...@g mail.com>
    wrote:
    Hi,
    >
    I am trying to convert some unmanaged code (C++) to managed code
    (using C++/CLI).
    >
    1) One of the functions used returns a void* which I need to cast into
    a handle of a managed object. Can somebody please tell me how.
    >
    Actually, the function that returns a void* is a part of a MFC class -
    CPtrList, used in my unmanaged code. I was searching of its equivalent
    in .NET, but couldn't find it. Is there any equivalent?
    >
    2) Also, is there any equivalent of double pointers **, in .NET
    handles?
    >
    Thanks in advance,
    Vijay.

    Comment

    • Tamas Demjen

      #3
      Re: Void pointer to managed object type

      vijay.gandhi@gm ail.com wrote:
      1) One of the functions used returns a void* which I need to cast into
      a handle of a managed object. Can somebody please tell me how.
      Typically you can solve that problem with the IntPtr type. Of course C#
      won't be able to interpret the meaning of IntPtr, but it can store its
      value, and when you pass it back to a C++ function, you can get the
      native pointer out of it. This is how handles (GDI or file handles) are
      implemented in .NET -- they are simply stored as IntPtr members.

      Note that the value of an IntPtr is not managed, it just contains a
      navite pointer address. The .NET framework doesn't know what to do with
      that address, and doesn't keep track of native objects where those
      IntPtrs point to. IntPtr is just as unsafe as a void*, because it
      contains no type information, and it may point to a dead object.
      Actually, the function that returns a void* is a part of a MFC class -
      CPtrList, used in my unmanaged code. I was searching of its equivalent
      in .NET, but couldn't find it. Is there any equivalent?
      Perhaps you could use List<IntPtr>, which is roughly analogous to
      vector<void*or CPtrList (not 100% identical, though). List<Tis in
      the System::Collect ions::Generic namespace.
      2) Also, is there any equivalent of double pointers **, in .NET
      handles?
      The short answer is no, but depending on what you are doing, there are
      alternative solutions to that problem.

      There's no such type as a handle to a handle, and you can't call the %
      operator to obtain a handle to a handle:

      MyRefClass^ c = gcnew MyRefClass;
      MyRefClass^^ p = %c; // error!!!

      You can, however, generate a tracking reference to a handle. Here are
      two examples:

      bool Allocate(Object ^% obj)
      {
      obj = gcnew String("hello") ;
      return true;
      }

      void Swap(Object^% one, Object^% two)
      {
      Object^ temp = one;
      one = two;
      two = temp;
      }

      In a similar way, you can get a tracking pointer to a handle too:

      ref class C
      {
      };

      void TestTrackingPoi nter()
      {
      C^ c = gcnew C;
      interior_ptr<C^ p = &c;
      }

      There are restrictions regarding tracking references and pointers. For
      example, they can't be declared as class members. They must be either
      function arguments or automatic (local) variables. When the garbage
      collector moves an object around in the memory, it updates all the
      tracking references and pointers to it. Tracking pointers can't be used
      in verifiable assemblies, because they can be freely incremented, and
      therefore they can point outside of the object's memory bounds. On the
      other hand, they're very fast. Unlike array indexing, interior_ptr is
      not bounds checked, and it is excellent for fast image processing routines.

      And finally, if you want to pass the address of a managed object to an
      unmanaged function, you can pin it using the pin_ptr keyword. While an
      object is pinned, the garbage collection won't move it around in the
      memory. That's yet another way of obtaining a pointer to managed memory.

      Tom

      Comment

      • Ben Voigt

        #4
        Re: Void pointer to managed object type


        "Tamas Demjen" <tdemjen@yahoo. comwrote in message
        news:ePQNdiAnHH A.3656@TK2MSFTN GP06.phx.gbl...
        vijay.gandhi@gm ail.com wrote:
        >
        >1) One of the functions used returns a void* which I need to cast into
        >a handle of a managed object. Can somebody please tell me how.
        >
        Typically you can solve that problem with the IntPtr type. Of course C#
        won't be able to interpret the meaning of IntPtr, but it can store its
        value, and when you pass it back to a C++ function, you can get the native
        pointer out of it. This is how handles (GDI or file handles) are
        implemented in .NET -- they are simply stored as IntPtr members.
        That's if you need to store a void* in a managed type. What it sounds like
        the OP needs, is to return a managed handle in an untyped way, like void*.
        You'd use System::Object^ for that, every managed handle can cast to and
        from Object^. There still needs to be a distinction between managed and
        unmanaged though, to keep the garbage collector informed. Specifically,
        storing the address of a managed object in a void* will leave you with a
        dangling pointer.
        >
        Note that the value of an IntPtr is not managed, it just contains a navite
        pointer address. The .NET framework doesn't know what to do with that
        address, and doesn't keep track of native objects where those IntPtrs
        point to. IntPtr is just as unsafe as a void*, because it contains no type
        information, and it may point to a dead object.
        >
        >Actually, the function that returns a void* is a part of a MFC class -
        >CPtrList, used in my unmanaged code. I was searching of its equivalent
        >in .NET, but couldn't find it. Is there any equivalent?
        >
        Perhaps you could use List<IntPtr>, which is roughly analogous to
        vector<void*or CPtrList (not 100% identical, though). List<Tis in the
        System::Collect ions::Generic namespace.
        >
        >2) Also, is there any equivalent of double pointers **, in .NET
        >handles?
        >
        The short answer is no, but depending on what you are doing, there are
        alternative solutions to that problem.
        >
        There's no such type as a handle to a handle, and you can't call the %
        Sure there is: a ref class.

        generic<typenam e To>
        ref struct Handle
        {
        To Target;
        };

        triple indirection on string: Handle<Handle<H andle<System::S tring^>^>^>

        mmm, syntax might be wrong, might need To^ Target and leave off the ^ when
        using.... I always use templates, not generics, when in C++/CLI.
        operator to obtain a handle to a handle:
        >
        MyRefClass^ c = gcnew MyRefClass;
        MyRefClass^^ p = %c; // error!!!
        >
        You can, however, generate a tracking reference to a handle. Here are two
        examples:
        >
        bool Allocate(Object ^% obj)
        {
        obj = gcnew String("hello") ;
        return true;
        }
        >
        void Swap(Object^% one, Object^% two)
        {
        Object^ temp = one;
        one = two;
        two = temp;
        }
        >
        In a similar way, you can get a tracking pointer to a handle too:
        >
        ref class C
        {
        };
        >
        void TestTrackingPoi nter()
        {
        C^ c = gcnew C;
        interior_ptr<C^ p = &c;
        }
        >
        There are restrictions regarding tracking references and pointers. For
        example, they can't be declared as class members. They must be either
        function arguments or automatic (local) variables. When the garbage
        collector moves an object around in the memory, it updates all the
        tracking references and pointers to it. Tracking pointers can't be used in
        verifiable assemblies, because they can be freely incremented, and
        therefore they can point outside of the object's memory bounds. On the
        other hand, they're very fast. Unlike array indexing, interior_ptr is not
        bounds checked, and it is excellent for fast image processing routines.
        >
        And finally, if you want to pass the address of a managed object to an
        unmanaged function, you can pin it using the pin_ptr keyword. While an
        object is pinned, the garbage collection won't move it around in the
        memory. That's yet another way of obtaining a pointer to managed memory.
        >
        Tom

        Comment

        Working...