I am calling a method from C# like this:
[DllImport(@"C:\Hash.dll",
CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr ph_dct_videohash(
string file,
ref int length);
static void Main(string[] args)
{
int length = 0;
ph_dct_videohash(@"C:\Users\shady\H.avi", ref length);
Console.Read();
}
And here is the method I am calling from the library
ulong64* ph_dct_videohash(const char *filename, int &Length){
CImgList<uint8_t> *keyframes = ph_getKeyFramesFromVideo(filename);
if (keyframes == NULL)
return NULL;
Length = keyframes->size();
ulong64 *hash = (ulong64*)malloc(sizeof(ulong64)*Length);
//some code to fill the hash array
return hash;}
The question is how can I retrieve the unsigned 64bit Long array in C# and free the memory after using it. It would be even better if it is managed by the garbage collector for me.
I tried Marshal.copy but it didn’t work and I am afraid there would be a mem leak (I don’t know whether the mem will be freed automatically or not). Any help would be appreciated. Thanks.
You have two ways that you can follow:
Add “free” function to your library and call it explicitly for each resource allocated on library’s side. This requires the least amount of code changes on library side, but you have to remember about freeing the memory, unless you’ll create some
IDisposablewrapper forIntPtrthat will do the job automatically. For example, you could use this class:Change public library’s functions to accept pointers to buffers instead of allocating them internally. This potentially requires lots of changes on library side, but simplifies the code on C# side.
EDIT: as a suppliment for the first suggestion, you could use following class:
Just create an instance of it for each IntPtr result. You can then either call
Disposemanually when you want the memory to be freed, or you can just leave it hanging and it will be picked up by GC eventually (although I don’t recommend it). You can read more about disposing unmanaged data here