Вот код C #, который я получил (я думаю из примера кода BIOAPI) давным-давно для взаимодействия с BioAPI . Метод DoMarshall возвращает IntPtr, указывающий на выделенную память, достаточно большую для хранения массива.
Я не работал с Managed C ++, поэтому я не уверен, какие изменения необходимы, но, возможно, это укажет вам правильное направление. Я работал с УПЭК в то время. Надеюсь, это поможет ...
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public class BioAPI_DATA
{
public uint Length = 0;
public byte[] Data = null;
public BioAPI_DATA() {}
public BioAPI_DATA(uint length, byte[] data) { Length = length; Data = data; }
public IntPtr DoMarshal(ref int size)
{
IntPtr ptr;
IntPtr ptrData = IntPtr.Zero;
int ofs = 0;
size = Marshal.SizeOf(Type.GetType("System.Int32")) +
Marshal.SizeOf(Type.GetType("System.IntPtr"));
ptr = Marshal.AllocCoTaskMem( size );
Marshal.WriteInt32(ptr, ofs, (int) Length);
ofs += Marshal.SizeOf(Type.GetType("System.Int32"));
if (Data != null)
{
ptrData = Marshal.AllocCoTaskMem( Data.Length );
Marshal.Copy(Data, 0, ptrData, Data.Length);
}
Marshal.WriteIntPtr(ptr, ofs, ptrData);
return ptr;
}
public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
{
int ofs = 0;
size = Marshal.SizeOf(Type.GetType("System.Int32")) +
Marshal.SizeOf(Type.GetType("System.IntPtr"));
Length = (uint) Marshal.ReadInt32( ptr, ofs );
ofs += Marshal.SizeOf(Type.GetType("System.Int32"));
if (Length == 0)
{
if (Data != null) Data = null;
return;
}
IntPtr ptr2 = Marshal.ReadIntPtr(ptr, ofs);
if (Data == null || Data.Length != Length) Data = new byte[Length];
Marshal.Copy(ptr2, Data, 0, (int) Length);
if (fDeleteOld) { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
}
}