I'm writting a Managed C++ library to call into legacy C API.
I need to allocate a few arrays of C strutures.
Inititally I used 'new MyStruct[SIZE]', but when I have a few of them in a
row, writing all the try/catch to check for out of memory exception and
deleting every one that should be was becoming quite cumbersome, not to
mention normale exception that could get through....
Finally after much discussion on this newsgroup and many usefull suggestion
(thank you everyone) I finally made up this simple managed solution (wich I
could use in my managed class, unlike std::auto_ptr or std::vector!!).
I just put here for review so expert Managed C++ programmer could give me
their opinion.
---- 1st a sample, class code below ---
// C API
struct ASTruct
{
// members
};
bool AFunction(struct AStruct* p_s, int len);
// sample, showing typical usage
void doSomething(int N)
{
CArray<struct AStruct>^ pa = gcnew CArray<struct AStruct>(N);
while( !AFunction(pa->get(), pa->Length) )
pa->Length += N;
}
----- the code ------
#pragma once
#include "stdlib.h"
template <class T>
public ref class CArray : System::IDisposable
{
public:
CArray(int capacity) : length(capacity)
{
if(length < 0)
throw gcnew System::ArgumentOutOfRangeException();
ptr = (T*) malloc(length * sizeof(T));
if( !ptr )
throw gcnew System::OutOfMemoryException();
}
property int Length
{
inline int get() { return length; }
void set(int newlength)
{
if(newlength < 0)
throw gcnew System::ArgumentOutOfRangeException();
T* newptr = (T*) realloc((void*) ptr, newlength * sizeof(T));
if( !newptr )
throw gcnew System::OutOfMemoryException();
ptr = newptr;
}
}
// just be careful, OK?!
inline T* operator[](int index) { return ptr+index; }
inline T* operator+(int index) { return ptr+index; }
inline operator T*() { return ptr; }
inline T* operator->() { return ptr; }
inline T* Get() { return ptr; }
private:
~CArray()
{
if( ptr ) // I'm not sure of what IDisposable will do...
free( ptr );
ptr = nullptr;
}
int length;
T* ptr;
CArray(const CArray%);
CArray% operator=(const CArray%);
};