C# IntPtr的大小问题 昨天,我发布了一个关于从C到C++传递一些int和double **的问题。p>

C# IntPtr的大小问题 昨天,我发布了一个关于从C到C++传递一些int和double **的问题。p>,c#,c++,marshalling,intptr,C#,C++,Marshalling,Intptr,幸运的是,我得到了一些很好的帮助。这是我的新代码: [DllImport("opendsp.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] public unsafe static extern int SetAcquisitionPointerSynchronously(int* ID, int* BufferID, out IntPtr P

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

[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;
    }
[DllImport(“opendsp.dll”,SetLastError=true,CharSet=CharSet.Auto,CallingConvention=CallingConvention.Cdecl)]
同步公开不安全的静态外部int SetAcquisitionPointers(int*ID,int*BufferID,out IntPtr指针,out IntPtr时间,int NumberOfPointers);
公共不安全int OpenDSP_setAcquisitionPointers同步(int[]ID、int[]BufferID、ref int[]指针、ref double[]时间、int NumberOfPointers)
{
IntPtr fQueue=IntPtr.Zero;
IntPtr fTime=IntPtr.Zero;
int-breturn=-1;
固定(int*fMeasurementId=IDs)
固定(int*fBufferID=BufferID)
尝试
{
fQueue=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int))*Pointer.Length);
fTime=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Double))*Time.Length;
breturn=同步设置采集点(fMeasurementId、fBufferID、out FQUE、out fTime、NumberOfPointers);
int size=Marshal.SizeOf(typeof(double));
对于(uint i=0;i
当我的两个数组指针和时间的长度为2时,我没有问题。但是当我把它增加到4时,我的代码崩溃了。我调试过,当它试图访问指针的第四个元素时,这个元素指向x00000,所以它不可访问。 我尝试过不同的事情,但没有成功。
如果有人遇到同样的问题,我已经找到了一个解决方案:

C++代码:

int SetPointers(int* ID, int* BufferID, int** Pointer, double** Time, int NumberOfPointers);
C#代码:

[DllImport(“mydll.dll”,CallingConvention=CallingConvention.Cdecl)]
私有静态外部Int32设置指针(Int32[]ID、Int32[]BufferID、IntPtr[]Pointer、IntPtr[]Time、int NumberOfPointers);
公共不安全的int设置指针(int[]id、int[]BufferID、ref int[]Pointer、ref double[]Time、int NumberOfPointers)
{
int-breturn=-1;
IntPtr[]队列=新IntPtr[NumberOfPointers];
IntPtr[]时间=新IntPtr[NumberOfPointers];
for(int i=0;i=0)
{
for(int i=0;i
此代码有非常严重的错误,永远无法按编写的方式工作。非托管函数的语义非常重要,但非常不清楚。可以肯定的是,您使用它是完全错误的,它需要稳定的指向内存的指针,一个指向数组的指针数组,而不是在调用后将它们取消分配。使用fixed是非常错误的。我强烈建议你用C++/CLI编写一个包装器,而不是尝试pinvoke。是的,Hans所说的,一个不平凡的pinvoke是两场战斗,让代码编译只是第一场战斗,让它真正正确运行是另一场蠕虫、蜡罐等等。
[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;
    }