Thank you for your answer, I'll be more specific:
my C# application allocates memory using Marshal.AllocCoTaskMem(),
then fill the unmanaged memory just allocated with
Marshal.StructureToPtr() for class or Marshal.Copy() for arrays.
I allocate also unmanaged memory for the return values and only
when all data is copied to the new memory I call the C library. After
the call some return values are written by C library in the unmanaged
memory block, then this memory is copied back into C# managed
structure (Marshal.PtrToStructure())
In fact C# allocates and frees memory, whereas the C library just make
some processing and writes values in that memory that C# has prepared
few lines above the function.
DestroyStructure should almost never be called.
FreeCoTaskMem should be called if the DLL returns memory to you that
was allocated with CoTaskMemAlloc or similar API.
Please do, and be specific about who allocates memory and who is
responsible for freeing it, and using which allocator API.
Code:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class myClassA
{
public Int32 n_elem;
public IntPtr temperature = IntPtr.Zero;
public IntPtr length = IntPtr.Zero;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class myClassB
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public char[] identifier = new char[8];
public Double weight = 0F;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public Double[] coeffs = new Double[3];
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public myClassC
{
public IntPtr ptrClassA;
public IntPtr ptrClassB;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class myClassOut
{
public Int32 iteration;
public Single avgTemp;
}
Code:
myClassA classAObject = new myClassA();
myClassB classBObject = new myClassB();
myClassC classCObject = new myClassC();
myClassOut classOutObject = new myClassOut();
classAObject.n_elem = rowsCount;//it is the rows number returning from
a SELECT in ORACLE
Double[] temp = new Double[rowsCount];
Double[] len = new Double[rowsCount];
//loop filling temp and len with query results
{...}
classAObject.temperature = ConvertEx.ArrayToPtr(temp) ;
classAObject.length = ConvertEx.ArrayToPtr(len);
classCObject.ptrClassA = ConvertEx.StructToPtr(classAObject );
classCObject.ptrClassB = ConvertEx.StructToPtr(classBObject );
IntPtr ptrIn = ConvertEx.StructToPtr(classCObject);
IntPtr ptrOut = ConvertEx.StructToPtr(classOutObject);
CLibrary(ptrIn,ptrOut);
Marshal.PtrToStructure(ptrOut,classOutObject);
{some processing}
{
release memory --> Now i call FreeCoTaskMem()
but from same MSDN example i understand that I should call also
DestroyStructure on object like ClassCObject and after FreeCoTaskMem
on the IntPtr variable
}
The application cyclically (every 3 seconds) performs a calculation
using the C library, the communication between C# and C is ok because
the library calculates correctly and I verify the value in memory and
in some log file that C library writes and they are always correct, my
really trouble is on memory occupation, after some hours (about a
night) of execution the occupation of C# application is huge (about
1GB).
benjo