C++/CLI issue: using STL and CLI value types (C# structs)

  • Thread starter Thread starter John
  • Start date Start date
J

John

I'm having a major problem trying to use value types like
System::Drawing::Rectangle with std::vector. Is it possible to use STL
containers with these type of objects, or am I just doing something wrong?

Thanks!

[ -- code snippet -- ]
using namespace System::Drawing;
#include <vector>

public ref class Base
{
static void GetQuads( Base^ root )
{
std::vector<Rectangle> q;
}
};


gives this error

C:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(1290) :
error C4439: 'std::_Ptr_cat' : function definition with a managed type
in the signature must have a __clrcall calling convention
2> C:\Program Files\Microsoft Visual Studio
8\VC\include\xmemory(226) : see reference to function template
instantiation 'std::_Nonscalar_ptr_iterator_tag
std::_Ptr_cat<_Ty*,_Ty*>(_T1 &,_T2 &)' being compiled
2> with
2> [
2> _Ty=System::Drawing::Rectangle,
2> _T1=System::Drawing::Rectangle *,
2> _T2=System::Drawing::Rectangle *
2> ]
2> C:\Program Files\Microsoft Visual Studio
8\VC\include\vector(1083) : see reference to function template
instantiation 'void
std::_Destroy_range<System::Drawing::Rectangle,std::allocator<_Ty>>(_Ty
*,_Ty *,_Alloc &)' being compiled
2> with
2> [
2> _Ty=System::Drawing::Rectangle,
2> _Alloc=std::allocator<System::Drawing::Rectangle>
2> ]
2> C:\Program Files\Microsoft Visual Studio
8\VC\include\vector(1082) : while compiling class template member
function 'void std::vector<_Ty>::_Destroy(System::Drawing::Rectangle
*,System::Drawing::Rectangle *)'
2> with
2> [
2> _Ty=System::Drawing::Rectangle
2> ]
2> c:\depot-jmatzen-mouse\depot\game14\src\engine\ui\Base.h(145)
: see reference to class template instantiation 'std::vector<_Ty>' being
compiled
2> with
2> [
2> _Ty=System::Drawing::Rectangle
2> ]
 
John said:
I'm having a major problem trying to use value types like
System::Drawing::Rectangle with std::vector. Is it possible to use
STL containers with these type of objects, or am I just doing
something wrong?

No, you're not doing anything wrong - it justs doesn't work.

There's a feature known as STL/CLR that was intended to be included in VC
2005 but they weren't able to get it done in time. When it's eventually
released, it'll directly address the kind of thing you're trying to do. In
the meantime, you have to settle with using framework containers for
framework objects.

See

http://msdn.microsoft.com/msdnmag/issues/06/04/PureC/default.aspx

for some background on STL/CLR. AFIAK, no release date for STL/CLR has been
announced

-cd
 
No, you're not doing anything wrong - it justs doesn't work.
The particular diagnostic sounds rather academic. Did you try to
downgrade/disable the error? I guess that won't work because
vector will use placement new.

Anyway for Rectangle, this might be used in COM Interop
and therefore should have sequential layout, which should
mean it's binary compatible with the corresponding native
type (RECT). So just using std::vector<RECT> with some
conversions should work just fine.

-hg
 
John said:
I'm having a major problem trying to use value types like
System::Drawing::Rectangle with std::vector. Is it possible to use STL
containers with these type of objects, or am I just doing something wrong?
Hi John,
try storing gcroot or auto_gcroot pointers of the managed objects in
order to embed them within native types like std:vector:

std::vector<gcroot<Rectangle^>> q;

See "Mix Types Safely and Correctly" in
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/CplusCLIBP.asp

Semmel
 
Semmel said:
try storing gcroot or auto_gcroot pointers of the managed objects in
order to embed them within native types like std:vector:

std::vector<gcroot<Rectangle^>> q;

A possible problem with this is that Rectangle becomes a GC type, which
means a hidden wrapper is created around it. This is called boxing, and
it's done implicitly. I'd consider using List<Rectangle>, and gcrooting
that if needed.

If gcroot is used, it requires a manual call to delete, as gcroot is
like a naked pointer. auto_gcroot is the exception safe version, but I'm
not sure if it can be stored in a container safely. It could be like
auto_ptr, which doesn't mix with STL.

Tom
 
Back
Top