473,468 Members | 1,771 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Handle to pointer conversion

I have been checking C++/CLI lately by using VC++ 2005 Express Beta 1
(should be called Alpha though).

In managed extensions we could pass managed pointers to functions taking
unmanaged pointers as parameters by using __pin pointers:
__gc class whatever
{
// ...
};
template<class T>
void somefun(T *p)
{
// ...
};

int main()
{
whatever *p=__gc new whatever;

whatever __pin *pp=p;

somefun(pp);

// ...
}

How can this handle to pointer conversion take place in C++/CLI? The
following does not seem to work:
ref class managed
{
};
int main()
{
using namespace stdcli::language;

managed ^h=gcnew managed;

pin_ptr<managed>p=h;
}
C:\c>cl /clr temp.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 14.00.40607.16
for Microsoft (R) .NET Framework version 2.00.40607.16
Copyright (C) Microsoft Corporation. All rights reserved.

temp.cpp
temp.cpp(12) : error C3833: 'managed' : invalid target type for pin_ptr
Cannot declare pin_ptr to a handle type. Consider declaring
pin_ptr to one of the members of 'managed'

C:\c>


Best regards,

Ioannis Vranos
Nov 17 '05 #1
7 1907
Ioannis Vranos wrote:
I have been checking C++/CLI lately by using VC++ 2005 Express Beta 1
(should be called Alpha though).
Actually, the alpha is something else entirely. We're getting very close to
publishing an update to the VC tools which has a far more complete set of
the syntax we want to support in Whidbey.
In managed extensions we could pass managed pointers to functions taking
unmanaged pointers as parameters by using __pin pointers:

[CODE SAMPLE]

How can this handle to pointer conversion take place in C++/CLI? The
following does not seem to work:

[SNIP]

temp.cpp
temp.cpp(12) : error C3833: 'managed' : invalid target type for pin_ptr
Cannot declare pin_ptr to a handle type. Consider declaring
pin_ptr to one of the members of 'managed'


The error message is correct (aside from the unfortunate use of "handle
type" which should be "ref class"). There is no way to directly pin a whole
object on the GC heap, nor is there any good reason to do so.

Since a whole object on a GC heap can never be passed to native code, it's
only the members of such an object that should be passed. Therefore, you
need to pin the member of the ref class that you want to pass to native
code.

FYI, by pinning a member of an object or an element of an array, you pin the
entire object or the entire array respectively.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.
Nov 17 '05 #2
Brandon Bray [MSFT] wrote:
The error message is correct (aside from the unfortunate use of "handle
type" which should be "ref class"). There is no way to directly pin a whole
object on the GC heap, nor is there any good reason to do so.
?!
Since a whole object on a GC heap can never be passed to native code, it's
only the members of such an object that should be passed. Therefore, you
need to pin the member of the ref class that you want to pass to native
code.

FYI, by pinning a member of an object or an element of an array, you pin the
entire object or the entire array respectively.


What do you mean by that. Consider a type describing a bank account:
ref class BankAccount
{
// ...
};

Suppose we have a list of some objects of this type and we have defined
comparison operators which in essence compare the money amounts of each
account, and we want to sort them based on those money with a sort
function (which could be the std::sort).
So why we can't pass these objects and only their members? This is a
rational thing to do and possible with managed extensions!
I suppose you know that passing objects to functions or methods is a
trivial thing in ISO C++!


Best regards,

Ioannis Vranos
Nov 17 '05 #3
Ioannis Vranos wrote:
Suppose we have a list of some objects of this type and we have defined
comparison operators which in essence compare the money amounts of each
account, and we want to sort them based on those money with a sort
function (which could be the std::sort).
It's useful to think of pinning as a dangerous operation. In addition to
fragility of holding pointers after they are no longer pinned, pinning also
introduce sand bars to the compaction algorithm which ultimately leads to
the garbage collector running more often which is not a good thing. (I could
spend quite a while describing how running the garbage collector too often
severely lowers the performance of your program.)
So why we can't pass these objects and only their members? This is a
rational thing to do and possible with managed extensions!
Pinning is meant to deal with data that should not move in memory because
native code is operating on that data. The only data that native code can
operate on is value types.

Using the STL algorithms is absolutely something that we want to support in
general. In fact, that is something we are planning on officially supporting
with the STL.NET library. The only difference between the standard
algorithms and the ones needed for managed programming is the usage of % to
bind references on the stack. No pinning is necessary at all.
I suppose you know that passing objects to functions or methods is a
trivial thing in ISO C++!


Of course, I do. However, pinning is not something that should be done
lightly. We designed a syntax and semantics that makes pinning rarer. C++
and all the new features in new C++ syntax support passing objects to
methods and binding references, and the new syntax even provides much better
support than the old syntax.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.
Nov 17 '05 #4
Brandon Bray [MSFT] wrote:
It's useful to think of pinning as a dangerous operation. In addition to
fragility of holding pointers after they are no longer pinned, pinning also
introduce sand bars to the compaction algorithm which ultimately leads to
the garbage collector running more often which is not a good thing. (I could
spend quite a while describing how running the garbage collector too often
severely lowers the performance of your program.)

OK, I understand that pinning is an inconvenient situation, however
since it is supported (and since the entire managed objects get pinned
anyway), why not being supported for the entire ref objects?
This could make the use of existing unmanaged facilities easier, like
the C++ standard library.
Pinning is meant to deal with data that should not move in memory because
native code is operating on that data. The only data that native code can
operate on is value types.
Not only. As I said previously in managed extensions you can do:
__gc class whatever
{
// ...
};
template<class T>
void somefun(T *p)
{
// ...
};

int main()
{
whatever *p=__gc new whatever;

whatever __pin *pp=p;

somefun(pp);

// ...
}


Using the STL algorithms is absolutely something that we want to support in
general. In fact, that is something we are planning on officially supporting
with the STL.NET library. The only difference between the standard
algorithms and the ones needed for managed programming is the usage of % to
bind references on the stack. No pinning is necessary at all.
Ok then, since pinning is such a nightmare, why can't you make
interior_ptr to work for managed types at least, since it does not
involve pinning?


I suppose you know that passing objects to functions or methods is a
trivial thing in ISO C++!

Of course, I do. However, pinning is not something that should be done
lightly. We designed a syntax and semantics that makes pinning rarer. C++
and all the new features in new C++ syntax support passing objects to
methods and binding references, and the new syntax even provides much better
support than the old syntax.


However functions taking pointers can't be used, while it was possible
with managed extensions! At least for template functions taking T*, this
should be possible.


Best regards,

Ioannis Vranos
Nov 17 '05 #5
Ioannis Vranos wrote:
Not only. As I said previously in managed extensions you can do:

__gc class whatever
{
// ...
};

template<class T>
void somefun(T *p)
{
// ...
};

int main()
{
whatever *p=__gc new whatever;
whatever __pin *pp=p;
somefun(pp);
// ...
}
You can do the following instead:

ref class whatever { /*...*/ };

template<class T>
void somefun(T p) { /*...*/ }

template<class T>
void somefun(T* p) { /*...*/ }

Simply add an overload that does not take pointers. The other overload can
even do pointer operations and deduce handle, interior_ptr, etc. (You could
even conceive of removing the T* overload and just leave the T overload.
Ok then, since pinning is such a nightmare, why can't you make
interior_ptr to work for managed types at least, since it does not
involve pinning?
You don't need pointers to these whole objects. Many of the STL container
algorithms work on things other than pointers, including sort. The only
problem is that they try to bind references, which is not allowed unless the
value does not move in memory. Replacing the references with tracking
references (%) is the solution.
However functions taking pointers can't be used, while it was possible
with managed extensions! At least for template functions taking T*, this
should be possible.


The functions taking pointers shouldn't be taking pointers. They should be
taking handles. A template function that takes just a T (not T* or T^) can
still use pointer algebra (dereference, comparison, etc.) and can take both
a pointer and handle. Alternatively, you can partially specialize the
templates so they take a handle instead and do something different.

Hope that makes sense!

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.
Nov 17 '05 #6
Brandon Bray [MSFT] wrote:
Simply add an overload that does not take pointers. The other overload can
even do pointer operations and deduce handle, interior_ptr, etc. (You could
even conceive of removing the T* overload and just leave the T overload.

Well templates taking handles as parameters work too. I am talking
mainly about unmanaged code, with pointer specialisations performing
operations on pointers/iterators like std::sort.

I know, MS will write standard library specialisations for handles,
however I am not MS-specific, and even in this case in the mean time we
could use these conversions to get the job done until MS produces
specialisations for all the standard library facilities.
You don't need pointers to these whole objects. Many of the STL container
algorithms work on things other than pointers, including sort.

Can you give an example with std::sort in particular?

The functions taking pointers shouldn't be taking pointers. They should be
taking handles. A template function that takes just a T (not T* or T^) can
still use pointer algebra (dereference, comparison, etc.) and can take both
a pointer and handle. Alternatively, you can partially specialize the
templates so they take a handle instead and do something different.


So the point is we can't work in mixed mode that easily any more!


Best regards,

Ioannis Vranos
Nov 17 '05 #7
Ioannis Vranos wrote:
Well templates taking handles as parameters work too. I am talking
mainly about unmanaged code, with pointer specialisations performing
operations on pointers/iterators like std::sort.
As sort works on a collection that has iterators, to make it work you can
use iterators that need not be pointers. Since template code is not
unmanaged unless you use the #pragma unmanaged facility, you will not have
unmanaged code. As such, pinning is a really bad idea.

Templates that are designed around pointers are not going to work for
handles. In the past, it was possible to reuse the templates for __gc
pointers by first pinning those pointers. That is a practice we want to
discourage.
I know, MS will write standard library specialisations for handles,
however I am not MS-specific, and even in this case in the mean time we
could use these conversions to get the job done until MS produces
specialisations for all the standard library facilities.
We're actually not writing specializations of the standard algorithms for
handles. There's no need to do so. The only change that needs to take place
is changing & to % in the _very few_ places where references are used.
Otherwise, there are no changes at all.

All of the standard algorithms work on iterators. It happens that in many
cases a pointer matches the semantics of an iterator, but an iterator does
not need to be a pointer. So any standard algorithm that requires a pointer
as an iterator is wrong.

This is why I suggested removing the overload that required a pointer.
Instead, you can just deduce the type and make sure it has the same algebra
as an iterator. Handles for the most part can do everything you want to do
with pointers (equality, assignment, dereference).
Can you give an example with std::sort in particular?
Not readily. Sort works on containers, and I don't have any managed
containers at hand that I can dump into a newsgroup message. When we get
further along with Visual C++ 2005, you'll be able to see the STL.NET
library. It introduces a number of new collections that are built on top of
ref classes, but all the template functions used for algorithms have very
little change.
So the point is we can't work in mixed mode that easily any more!


That's not quite correct. Mixed mode is better than ever. We have made it
more difficult to do some things that you should really strive to avoid at
all lengths. Pinning unnecessarily is one of those things you should avoid.
The template code you're using is not unmanaged code, so you should not pin.
It's better to look at the template code to see if it is making the right
assumptions.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.
Nov 17 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Christian Lammel | last post by:
i'm looking for a possibility in C# to get a unique Int32 handle for an object reference. This handle must later (within the same process of course) be convertible back to an object reference (call...
8
by: chessc4c6 | last post by:
The program below creates a char pointer call charPtr...... i then declare an char array string "Good Luck" When i assign charPtr = string, I expect an error. However, It actually runs and...
11
by: x-pander | last post by:
given the code: <file: c.c> typedef int quad_t; void w0(int *r, const quad_t *p) { *r = (*p); }
16
by: junky_fellow | last post by:
According to Section A6.6 Pointers and Integers (k & R) " A pointer to one type may be converted to a pointer to another type. The resulting pointer may cause addressing exceptions if the...
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
28
by: Wonder | last post by:
Hello, I'm confused by the pointer definition such as int *(p); It seems if the parenthesis close p, it defines only 3 integers. The star is just useless. It can be showed by my program: ...
49
by: elmar | last post by:
Hi Clers, If I look at my ~200000 lines of C code programmed over the past 15 years, there is one annoying thing in this smart language, which somehow reduces the 'beauty' of the source code...
3
by: Peterwkc | last post by:
Hello all C++ expert programmer, I have a handle class which point to another class and use the pointer as object. I follow the code from C++ articles submited by someone in this forum....
8
by: tfelb | last post by:
Hey group! I have 2 questions. I saw functions with char *dst = (char *)src. In that case if I remember what I've learned I assign (an) (the) address of src to dst. Right? But I can assign...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.