1

私はこのコードを持っています(C#のNokia PC Connectivity 3.2サンプルコードから):

  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、例外がなくなるようです。

ここで何が起こっているのか、そして例外を防ぐ正しい方法は何ですか?

4

4 に答える 4

5

問題は、Marshal.StructureToPtrにtrueを渡して、2つの文字列ポインター(無効な場合もある)を解放しようとすることです。このインスタンスでは、そのメモリをヒープに割り当てただけなので、falseを渡す必要があります。(つまり、そこに解放するものは何もありません)。

于 2009-06-16T15:57:32.633 に答える
0

固定キーワードを使用して、元のへのポインタを取得しますfolderInfo

于 2009-06-15T10:09:57.833 に答える
0

管理されていないリソースが何かによって解放されていない可能性があります。使用しているものがIDisposableを実装しているかどうかを確認し、実装している場合は、ブロックでラップしusing { }ます。

于 2009-06-15T10:16:29.550 に答える
0

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
于 2009-06-15T21:39:29.120 に答える