问题与IntPtr的大小

时间:2013-11-27 12:10:43

标签: c# c++ marshalling intptr

昨天,我发布了一个关于将一些int **和double **从C#传递给C ++的问题。 How to import a C++ function with int** and double** parameters

幸运的是,我得到了一些很好的帮助。这是我的新代码:

[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;
    }

当我的两个数组指针和时间长度为2时,我没有问题。但是当我将它增加到4时,我的代码崩溃了。我调试了,似乎当它试图访问Pointer的第4个元素时,这个指向x00000,因此无法访问。 我尝试了不同的事情但没有成功。 关于如何解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:0)

如果有人遇到同样的问题,我找到了解决方案:

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;
    }