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 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.
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
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.
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
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.
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
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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);
}
|
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...
|
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 =...
|
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:
...
|
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...
|
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....
|
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...
|
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...
|
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,...
|
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...
|
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...
|
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...
|
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,...
|
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...
|
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...
|
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...
| |