I have the following class
public class ExrDepthMapExtractor : IDepthMapExtractor
{
public RawDepthMap GetDepthMap(string filePath)
{
return DepthMapExtractorService.ExtractDepthMapAs1DArray(filePath, Callbacks.ProgressCallback);
}
}
This calls the static C++ API wrapper
public static class DepthMapExtractorService
{
[DllImport("Blundergat.OpenExr.Adapter.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static unsafe extern bool ExtractDepthMapAs1DArray(
out ItemsSafeHandle vectorHandle,
out double* points,
out int width,
out int height,
string filePath,
Callbacks.ProgressFunc progressCallback);
[DllImport("Blundergat.OpenExr.Adapter.dll", CallingConvention = CallingConvention.Cdecl)]
private static unsafe extern bool Release(IntPtr itemsHandle);
public static unsafe RawDepthMap ExtractDepthMapAs1DArray(string filePath,
Callbacks.ProgressFunc progressCallback)
{
using (InternalExtractDepthMapAs1DArrayWrapper(filePath, out RawDepthMap rdm, progressCallback))
{
rdm.Source = filePath;
return rdm;
}
}
private static unsafe ItemsSafeHandle InternalExtractDepthMapAs1DArrayWrapper(
string filePath, out RawDepthMap rdm, Callbacks.ProgressFunc progressCallback)
{
double* pixels;
int width, height;
ItemsSafeHandle itemsHandle;
if (!ExtractDepthMapAs1DArray(out itemsHandle, out pixels, out width, out height, filePath, progressCallback))
throw new InvalidOperationException();
var pixelList = new List<double>();
for (int i = 0; i < width * height; i++)
pixelList.Add(pixels[i]);
rdm = new RawDepthMap()
{
Source = filePath,
DepthMapArray = pixelList,
Height = height,
Width = width
};
return itemsHandle;
}
public class ItemsSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public ItemsSafeHandle() : base(true) { }
protected override bool ReleaseHandle()
{
return Release(handle);
}
}
}
In my C++ I Release the ArrayHandle
as follows
#include "wrappers.h"
bool ExtractDepthMapAs1DArray(ArrayHandle* arrayHandle,
double** pixels,
int* width,
int* height,
const char* filePath,
ProgressFunc progressCallback)
{
try
{
auto v = new std::vector<double>();
ExrDepthMapExtractor exrExtractor;
*v = exrExtractor.extractDepthMap(filePath, *width, *height, progressCallback);
*arrayHandle = reinterpret_cast<ArrayHandle>(v);
*pixels = v->data();
if (progressCallback != NULL)
{
std::string strFilePath(filePath);
std::string message = "Extracted depth map from \"" + strFilePath + "\" successfully";
if (progressCallback != NULL)
progressCallback(message.c_str());
}
return true;
}
catch (...)
{
return false;
}
}
bool Release(ArrayHandle arrayHandle)
{
auto items = reinterpret_cast<std::vector<double>*>(arrayHandle);
delete items;
return true;
}
I have not used this before and the implementation was taken from [SO] (https://stackoverflow.com/questions/31417688/passing-a-vector-array-from-unmanaged-c-to-c-sharp), however, the way this is done does not look right to me and MSDN is different. The code seems to work fine with no memory leaks, but am I doing this the right way?