Marshalling: How to delete dynamic array from managed code.


A

Ananas

Hi,

My native C++ function creates a dynamic array. I'm marshalling it to
managed code and got to delete after. How to make it:

c++ code:

void CreateArrayInside( pTestStruct &TestStruct,
unsigned int &size)
{
size = 5000;

// test structure
TestStruct = new CTestStruct[size];
}

c# declaration:
[DllImport( "MathDll.dll", CharSet = CharSet.Auto, EntryPoint =
"CreateArrayInside" )]
public static extern void CreateArrayInside( ref IntPtr
TestStructArray, out uint size );

c# usage:


IntPtr pTestStructs = new IntPtr();
uint Count;

for ( uint i = 0; i < 20000; i++ )
{
MathDLLWrapper.Interface.CreateArrayInside( ref pTestStructs, out
Count );

// Marshal.FreeCoTaskMem( pTestStructs );

Console.WriteLine("Loop: " + i);
}

I tried to use Marshal.FreeCoTaskMem( pTestStructs ) but memory get
leaks. As it is said in the msdn the FreeCoTaskMem got to be used for
to free up memory allocated for COM tasks.

Is there any way to free up memory allocated by C++ part?

Please give an advise.

Thanks,
Eugene.

Marshal.FreeHGlobal( pTestStructs );
 
Ad

Advertisements

W

Willy Denoyette [MVP]

Ananas said:
Hi,

My native C++ function creates a dynamic array. I'm marshalling it to
managed code and got to delete after. How to make it:

c++ code:

void CreateArrayInside( pTestStruct &TestStruct,
unsigned int &size)
{
size = 5000;

// test structure
TestStruct = new CTestStruct[size];
}

c# declaration:
[DllImport( "MathDll.dll", CharSet = CharSet.Auto, EntryPoint =
"CreateArrayInside" )]
public static extern void CreateArrayInside( ref IntPtr
TestStructArray, out uint size );

c# usage:


IntPtr pTestStructs = new IntPtr();
uint Count;

for ( uint i = 0; i < 20000; i++ )
{
MathDLLWrapper.Interface.CreateArrayInside( ref pTestStructs, out
Count );

// Marshal.FreeCoTaskMem( pTestStructs );

Console.WriteLine("Loop: " + i);
}

I tried to use Marshal.FreeCoTaskMem( pTestStructs ) but memory get
leaks. As it is said in the msdn the FreeCoTaskMem got to be used for
to free up memory allocated for COM tasks.

Is there any way to free up memory allocated by C++ part?

Please give an advise.

Thanks,
Eugene.

Marshal.FreeHGlobal( pTestStructs );


You have to provide a C++ function that deletes the unmanaged memory allocated by the new
operator, the managed code has to call this function when done with it.

Willy.
 
A

Ananas

I did provided this function, it looked like this:

void DeletePtr(void *Ptr)
{
delete[] Ptr;
}

but I get a memory error in managed part.

Could you say what is incorrect?

"""Willy Denoyette [MVP] ÐÉÓÁÌ(Á):
"""
Ananas said:
Hi,

My native C++ function creates a dynamic array. I'm marshalling it to
managed code and got to delete after. How to make it:

c++ code:

void CreateArrayInside( pTestStruct &TestStruct,
unsigned int &size)
{
size = 5000;

// test structure
TestStruct = new CTestStruct[size];
}

c# declaration:
[DllImport( "MathDll.dll", CharSet = CharSet.Auto, EntryPoint =
"CreateArrayInside" )]
public static extern void CreateArrayInside( ref IntPtr
TestStructArray, out uint size );

c# usage:


IntPtr pTestStructs = new IntPtr();
uint Count;

for ( uint i = 0; i < 20000; i++ )
{
MathDLLWrapper.Interface.CreateArrayInside( ref pTestStructs, out
Count );

// Marshal.FreeCoTaskMem( pTestStructs );

Console.WriteLine("Loop: " + i);
}

I tried to use Marshal.FreeCoTaskMem( pTestStructs ) but memory get
leaks. As it is said in the msdn the FreeCoTaskMem got to be used for
to free up memory allocated for COM tasks.

Is there any way to free up memory allocated by C++ part?

Please give an advise.

Thanks,
Eugene.

Marshal.FreeHGlobal( pTestStructs );


You have to provide a C++ function that deletes the unmanaged memory allocated by the new
operator, the managed code has to call this function when done with it.

Willy.
 
W

Willy Denoyette [MVP]

Ananas said:
I did provided this function, it looked like this:

void DeletePtr(void *Ptr)
{
delete[] Ptr;
}

but I get a memory error in managed part.

Could you say what is incorrect?

You new'd an object in C++, it's up to delete this object in C++, no need to pass the
pointer to and from managed code.

void DeletePtr()
{
if(TestStruct)
delete[] TestStruct;
}

Willy.
 
A

Ananas

But if I want to pass a pointer from managed memory how should I go?
Actually it is not good to create for each pointer function deleting
the memory.


"""Willy Denoyette [MVP] ÐÉÓÁÌ(Á):
"""
Ananas said:
I did provided this function, it looked like this:

void DeletePtr(void *Ptr)
{
delete[] Ptr;
}

but I get a memory error in managed part.

Could you say what is incorrect?

You new'd an object in C++, it's up to delete this object in C++, no need to pass the
pointer to and from managed code.

void DeletePtr()
{
if(TestStruct)
delete[] TestStruct;
}

Willy.
 
W

Willy Denoyette [MVP]

Ananas said:
But if I want to pass a pointer from managed memory how should I go?
Actually it is not good to create for each pointer function deleting
the memory.

I really don't know what you are trying to achieve, but following should work....

// CS file

[DllImport("xxxxx.dll"), SuppressUnmanagedCodeSecurity]
static extern void CreateArrayInside(out IntPtr d, out int size);
[DllImport("xxxxx.dll"), SuppressUnmanagedCodeSecurity]
static extern void DeleteArray(IntPtr d);
static void Main()
{
IntPtr ptr = IntPtr.Zero;
int size;
GetArray(out ptr, out size);
// access data through unmanaged pointer here.... this will require Marshal.xxxxx calls
...
DeleteArray(ptr);
}
}

// CPP file
struct MyStruct {
long l;
unsigned char c;
};


extern "C" void __declspec(dllexport) __stdcall CreateArrayInside(MyStruct **ptr, unsigned
int &size)
{
size = 100;
*ptr = new MyStruct[size];
ptr[0]->l = 123456;
}

// delete memory pointed by ptr, oh what do I hate these void* ........
extern "C" void __declspec(dllexport) __stdcall DeleteArray(void *ptr)
{
if(ptr)
delete[] ptr;
}

Willy.
 
Ad

Advertisements

A

Ananas

OK, thank you, I got it working.


"""Willy Denoyette [MVP] ÐÉÓÁÌ(Á):
"""
Ananas said:
But if I want to pass a pointer from managed memory how should I go?
Actually it is not good to create for each pointer function deleting
the memory.

I really don't know what you are trying to achieve, but following should work....

// CS file

[DllImport("xxxxx.dll"), SuppressUnmanagedCodeSecurity]
static extern void CreateArrayInside(out IntPtr d, out int size);
[DllImport("xxxxx.dll"), SuppressUnmanagedCodeSecurity]
static extern void DeleteArray(IntPtr d);
static void Main()
{
IntPtr ptr = IntPtr.Zero;
int size;
GetArray(out ptr, out size);
// access data through unmanaged pointer here.... this will require Marshal.xxxxx calls
...
DeleteArray(ptr);
}
}

// CPP file
struct MyStruct {
long l;
unsigned char c;
};


extern "C" void __declspec(dllexport) __stdcall CreateArrayInside(MyStruct **ptr, unsigned
int &size)
{
size = 100;
*ptr = new MyStruct[size];
ptr[0]->l = 123456;
}

// delete memory pointed by ptr, oh what do I hate these void* ........
extern "C" void __declspec(dllexport) __stdcall DeleteArray(void *ptr)
{
if(ptr)
delete[] ptr;
}

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top