Question

OS : xp
IDE : VS 2008
In the project that i'm doing in visual C++ i have declared a std::vector inside managed class as so

std::vector<pts> dataPoints;//this gives error c4368 : mixed type not allowed 

but this works

std::vector<pts> * dataPoints;//a pointer to the vector  

i then have created this vector on the free store as so in the constructor of the managed class

dataPoints = new std::vector<pts>(noOfElements,pts());//which is not so attractive.

the reason i need vector is because there is file that i'm reading through the ifstream and storing those values in the vector.
Q1) why is that i'm able to declare a pointer to object of native type(i guess)but not an object? furthermore, prior to trying vector i tried the managed array as so

cli::array<Point> dataPoints //and i defined it later.

but when i do this

ifile >> dataPoints[i].X;   

it gives an error c2678 : operator= is not overloaded for int!!.
Q2) why is it that i cant use a managed code here. At first i thought it might be a wrapper class Int but then autounboxing(conversion operators) should take care of it?or is it that Point::X is qualified with property and thus is not recognized as normal int? what am i missing?. this is the reason i went for vector and pts solution.
pts is as follows

 struct pts
{
  int X, int Y;
  pts() : X(0),Y(0){}
  pts(int x,int y) : X(x),Y(y){}
};//this i created to store the data from the file.
Was it helpful?

Solution

An important property of managed class objects is that they get moved by the garbage collector. This happens when it compacts the heap. That plays havoc with native C++ objects, pointers to their members will become invalid. So as a rule, the compiler forbids embedding a native non-POD object inside a managed one. A pointer is not a problem.

The exact same problem exists for your use of the >> operator. The int gets passed by reference to operator>>(). Disaster strikes if the garbage collector kicks in right between the code taking the reference of the int and calling the operator. A simple workaround for that one is an intermediate step through a local variable:

int x;
ifile >> x;
dataPoint[i].X = x;

Which works because local variables are stable and are not subject to garbage collection.

None of this is a problem in native code. Do keep in mind that your ref class can easily call a native function. So separating the two can be useful and/or necessary.

OTHER TIPS

You can't directly contain a native type within a managed type: this is just a restriction on C++/CLI. I'm thinking this might be to do with the possibilities of pointers within the native type. If the native type is directly within the managed type, then when managed objects get shuffled around during garbage collection, then these pointers would point to the original, now incorrect, memory.

Therefore the native object needs to be on the heap, so that its internals don't get changed by garbage collection. So you need to hold the vector as a pointer, and delete it appropriately. Note that the latter isn't entirely trivial, and you need to have some knowledge of C++/CLI (which differs subtly from C#). See http://msdn.microsoft.com/en-us/library/ms177197(v=vs.100).aspx.

Looking at the last time I did this, in my file I had

public:
    !NetClass();
    ~NetClass() { this->!NetClass(); } // avoid arning C4461
private:
    class NativeImpl* const m_pImpl; // can't contain NativeImpldirectly

And in the cpp file I had

NetClass::!NetClass()
{
    // implement finalizer in ref class
    delete m_pImpl;
}

You might just want to use the pimpl idiom here if you have more than one native class to contain. See Why should the "PIMPL" idiom be used?.

Finally, I last did this quite a while ago, and I'm just saying what worked for me at the time. If you're doing this, you really need to know what you're doing. I used a book called C++/CLI in Action, which I'd recommend.

Edit

This article on STL/CLR looks interesting: http://blogs.msdn.com/b/nikolad/archive/2006/06/16/stlclr-intro.aspx. To quote

STL/CLR, originally called STL.NET, is an implementation of Standard Template Library (STL) that can operate with objects of managed types. VC++ already has implementation of STL, however it is currently working only with native types.

(I can't really help on your Q2)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top