我有这样一段代码(从诺基亚PC连接3.2示例代码,在C#):

  DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo =
  new DAContentAccessDefinitions.CA_FOLDER_INFO();
  folderInfo.iSize = Marshal.SizeOf(folderInfo); //(32)

  IntPtr bufItem = Marshal.AllocHGlobal(folderInfo.iSize);

  //I often get a AccessViolationException on the following line
  Marshal.StructureToPtr(folderInfo, bufItem, true);

如果我在此开始运行GC.Collect()的话,我没有得到一个AccessViolationException。但我不希望这个功能,除非必要慢下来。我试图把GC.Keepalive在不同的地方,但都没有成功。

CA_FOLDER_INFO定义为:

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct CA_FOLDER_INFO
    {
        public int iSize;
        public int iFolderId;
        public int iOptions;
        public string pstrName;
        public string pstrPath;
        public int iSubFolderCount;
        public IntPtr pSubFolders;
        public IntPtr pParent;
    }

我不这样做,在这种情况下,都要求使用字符串,并改变它们的定义,以IntPtr似乎使异常消失。

这是怎么回事,什么是防止异常的正确方法是什么?

有帮助吗?

解决方案

您的问题是,你传递真实Marshal.StructureToPtr所以尝试释放两个字符串指针(这有时是无效的)。你需要,因为你只是在堆中分配内存在这种情况下通过假。 (即没有什么释放那里)。

其他提示

您确定Marshal.Sizeof(bufItem)和Marshal.Sizeof(folderInfo)是一样的吗?

和,也许是事实,你不能初始化字符串?既然你说,当他们的IntPtr(默认为IntPtr.Zero)你没有得到的错误,我想尝试他们两个设置为空字符串您尝试编组缓冲区项目之前。

<强> [编辑]

也许你应该尝试钉住缓冲处理,并封送处理的结构,而不是可见光反之亦然。是这样的:

DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;

GCHandle pinnedHandle = GCHandle.Alloc(buffItem, GCHandleType.Pinned);
folderInfo = (DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(pin.AddrOfPinnedObject(), typeof(DAContentAccessDefinitions.CA_FOLDER_INFO));
pin.Free();

//folderInfo should contain the data from buffItem

使用固定的关键字,以得到一个指向原来的folderInfo

这可能是因为非托管资源没有被释放的东西。检查是否有任何你使用工具 IDisposable的和如果是这样,它包装在一个using { }块。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top