Вчера я опубликовал вопрос о передаче некоторых int ** и double ** из C # в C ++. Как импортировать функцию C ++ с параметрами int ** и double **
К счастью, я получил хорошую помощь. Вот мой новый код:
[DllImport("opendsp.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern int SetAcquisitionPointerSynchronously(int* ID, int* BufferID, out IntPtr Pointer, out IntPtr Time, int NumberOfPointers);
public unsafe int OpenDSP_SetAcquisitionPointerSynchronously(int[] IDs, int[] BufferID, ref int[] Pointer, ref double[] Time, int NumberOfPointers)
{
IntPtr fQueue = IntPtr.Zero;
IntPtr fTime = IntPtr.Zero;
int breturn = -1;
fixed (int* fMeasurementId = IDs)
fixed (int* fBufferID = BufferID)
try
{
fQueue = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * Pointer.Length);
fTime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Double)) * Time.Length);
breturn = SetAcquisitionPointerSynchronously(fMeasurementId, fBufferID, out fQueue, out fTime, NumberOfPointers);
int size = Marshal.SizeOf(typeof(double));
for (uint i = 0; i < NumberOfPointers; i++)
Time[i] = (double)Marshal.PtrToStructure(new IntPtr(fTime.ToInt32() + (size * i)), typeof(double));
size = Marshal.SizeOf(typeof(int));
for (uint i = 0; i < NumberOfPointers; i++)
Pointer[i] = (int)Marshal.PtrToStructure(new IntPtr(fQueue.ToInt32() + (size * i)), typeof(int));
Marshal.FreeHGlobal(fQueue);
Marshal.FreeHGlobal(fTime);
}
catch { }
return breturn;
}
Когда мои два массива Pointer и Time имеют длину 2, у меня нет проблем. Но когда я увеличиваю его до 4, мой код падает. Я отладил, и кажется, что когда он пытается получить доступ к 4-м элементам Pointer, этот указывает на x00000, поэтому он не доступен.
Я пробовал разные вещи без успеха.
Любые идеи о том, как это исправить?
В случае, если кто-то получает ту же проблему, я нашел решение:
Код C ++:
int SetPointers(int* ID, int* BufferID, int** Pointer, double** Time, int NumberOfPointers);
Код C #:
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern Int32 SetPointers(Int32[] ID, Int32[] BufferID, IntPtr[] Pointer, IntPtr[] Time, int NumberOfPointers);
public unsafe int SetPointers(int[] IDs, int[] BufferID, ref int[] Pointer, ref double[] Time, int NumberOfPointers)
{
int breturn = -1;
IntPtr[] queue = new IntPtr[NumberOfPointers];
IntPtr[] time = new IntPtr[NumberOfPointers];
for (int i = 0; i < NumberOfPointers; i++)
{
queue[i] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
time[i] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)));
}
breturn = SetPointers(IDs, BufferID, queue, time, NumberOfPointers);
if (breturn >= 0)
{
for (int i = 0; i < NumberOfPointers; i++)
{
Pointer[i] = (int)Marshal.ReadInt32(queue[i]);
Time[i] = (double)Marshal.PtrToStructure(new IntPtr(time[i].ToInt32()), typeof(double));
}
}
return breturn;
}
Других решений пока нет …