2009-06-15 11 views
1

が、私は(C#で、NokiaのPCの接続3.2サンプルコードからの)コードのこの部分を持っている理由私は理解していない実行:「GC.Collectは」私のクラッシュが修正されていますが、

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を入れてみましたが、成功しませんでした。私は、この例では、文字列のいずれかを必要としない

[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にその定義を変更すると、例外が離れて行くように思わ:

CA_FOLDER_INFOは、以下のように定義されます。

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

+4

あなたがbufItemで終わったら、try-finallyでMarshal.FreeHGlobalを呼び出すのを忘れないでください。 – sisve

答えて

5

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

+0

ありがとうございます、それはうまくいくようで、私が理解している説明です。 – Greg

0

オリジナルのfolderInfoへのポインタを取得するには、fixedキーワードを使用します。

0

管理されていないリソースが何かによって解放されていない可能性があります。使用しているものがIDisposableであるかどうかを確認し、もしそうなら、それをusing { }ブロックにまとめてください。

0

Marshal.Sizeof(bufItem)とMarshal.Sizeof(folderInfo)は同じですか?

文字列を初期化していない可能性がありますか? IntPtr(既定値はIntPtr.Zero)のときにエラーが発生しないと言うので、バッファ項目をマーシャリングする前に、両方を空の文字列に設定してみます。

[編集]

たぶん、あなたはその逆VISバッファハンドルを固定し、構造にそれをマーシャリングではなく、試してみてください。このような何か:

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 
+1

2つの文字列フィールドを ""またはString.Emptyに設定しても、AccessViolationExceptionは消えません。 – Greg

+1

サイズは同じです。 – Greg

関連する問題