IntPtr 大小的问题
Posted
技术标签:
【中文标题】IntPtr 大小的问题【英文标题】:issue with size of IntPtr 【发布时间】:2013-11-27 12:10:43 【问题描述】:昨天,我发布了一个关于将一些 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;
当我的两个数组 Pointer 和 Time 的长度为 2 时,我没有问题。但是当我将它增加到 4 时,我的代码就会崩溃。我调试了一下,似乎当它试图访问 Pointer 的第 4 个元素时,这个元素指向 x00000,因此无法访问。 我尝试了不同的事情但没有成功。 有关如何解决此问题的任何想法?
【问题讨论】:
这段代码有非常严重的错误,永远不能像写的那样工作。非托管函数的语义非常重要,但非常不清楚。很确定你完全错误地使用它,它需要稳定的内存指针,指向数组的指针数组,并且 not 在调用后将它们取消分配。 fixed 的使用是非常错误的。我强烈建议您在 C++/CLI 中编写一个包装器,而不是尝试调用它。 是的,Hans 所说的,一个不平凡的 pinvoke 是两场战斗,让代码编译只是第一场,让它真正正确运行完全是另一个蠕虫球,可以蜡,随便什么,。 【参考方案1】:如果有人遇到同样的问题,我已经找到了解决方案:
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;
【讨论】:
以上是关于IntPtr 大小的问题的主要内容,如果未能解决你的问题,请参考以下文章