Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / May 2007

Tip: Looking for answers? Try searching our database.

Void pointer to managed object type

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
vijay.gandhi@gmail.com - 19 May 2007 22:52 GMT
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 - 20 May 2007 20:20 GMT
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.PtrToStructure().  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(UnmanagedType.LPArray) 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...@gmail.com" <vijay.gan...@gmail.com>
wrote:
> Hi,
>
[quoted text clipped - 13 lines]
> Thanks in advance,
> Vijay.
Tamas Demjen - 22 May 2007 01:34 GMT
> 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<T> is in
the System::Collections::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 TestTrackingPointer()
{
   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
Ben Voigt - 22 May 2007 23:37 GMT
>> 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.
[quoted text clipped - 4 lines]
> 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
[quoted text clipped - 17 lines]
>
> There's no such type as a handle to a handle, and you can't call the %

Sure there is: a ref class.

generic<typename To>
ref struct Handle
{
   To Target;
};

triple indirection on string: Handle<Handle<Handle<System::String^>^>^>

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:
>
[quoted text clipped - 45 lines]
>
> Tom

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.