2009-08-11 16 views
0

私はStrCreateStorageExをC#で呼び出す方法を今一週間把握しようとしていますが、そのために提示しなければならないのはAccessViolationExceptionと頭痛です。C#のStgCreateStorageExはAccessViolationExceptionを返します

私はどのように機能を宣言するべきかわかりません。私は膨大な数のウェブサイトがそれを何百もの異なる方法で宣言しているのを見ました。しかし、これは私が現在持っているものです。

[DllImport("ole32.dll")] 
     public unsafe static extern UInt32 StgCreateStorageEx([MarshalAs(UnmanagedType.LPWStr)] string 
      pwcsName, long grfMode, STGFMT stgfmt, uint grfAttrs, IntPtr pStgOptions, IntPtr reserved2, [In] Guid riid, void** ppObjectOpen) 

私が見たサイトでは、私は最後のパラメータにMarshalAsを使用する必要が私に教えて、と私はIUnknownの、インタフェース、LPStruct、およびいくつかの他のものを使用してみました。私を得た唯一の事は、マーシャラーがデータ型について悩んでいたことです。私はおそらく関連している感情を得るが、それは私にそれがほしいと思わないものだけを教えるので、私はそれが何を望んでいるのか分からない。

私はどのように関数を呼び出しますか:これははるかに簡単に始めました。

IntPtr ptr2ptr2ptr = Marshal.AllocHGlobal(IntPtr.Size); 
IntPtr ptr2ptr = Marshal.AllocHGlobal(IntPtr.Size); 
IntPtr ptr2data = Marshal.AllocHGlobal(104857600); // pretty sure that's enough for whatever StgCreateStorageEx wants to do. 
Marshal.WriteIntPtr(ptr2ptr,ptr2data); 
Marshal.WriteIntPtr(ptr2ptr2ptr, ptr2ptr); 
Guid IID_IStorage = new Guid("0000000B-0000-0000-C000-000000000046"); 
UInt32 results; 

results = NativeMethods.StgCreateStorageEx(null, NativeMethods.STGM_READWRITE + NativeMethods.STGM_SHARE_EXCLUSIVE, 
        NativeMethods.STGFMT.STGFMT_STORAGE, 0, IntPtr.Zero, IntPtr.Zero, IID_IStorage, (void**)Marshal.ReadIntPtr(ptr2ptr2ptr).ToPointer()); 

:しかし、このようにあなたはこの混乱を持って、自分自身をメモリを管理することでしたメモリ違反を取得した後、私は読み始め、最終的には唯一の方法は、GCが私をねじ込むていなかったことを確認すべきという結論に達しました誰もがこの混乱をまっすぐに整える方法についてのアイディアを得て、それが実際に働くようにしましたか?

ところで、最終的な目標は、ツリービューからWindowsエクスプローラにフォルダをドラッグして、そのフォルダとその内容すべてをドロップした場所に書き込むことです。キャッチは、TreeViewはデータベースに完全に格納されたファイルシステムを表します。私が見つけることができる唯一の方法は、IStorageを渡すことでした。したがって、StgCreateStorageExを呼び出す必要があります。

+0

あなたはpinvoke.netを試したことがありますか? http://pinvoke.net/default.aspx/ole32/StgCreateStorageEx.htmlには、使用可能なOLE構造化ストレージを管理ラッパーがあることが記載されています。 –

+0

これは私が始めたところです。私が知る限り、System.IO.Packagingは既に存在するStoragesで作業するのに最適ですが、実際には新しいものを作成することはできません。 –

答えて

1

StgCreateStorageの署名とドキュメントからは、StgCreateStorageの署名とドキュメントから、StgCreateStorageが作成されたオブジェクトに値を設定できるように、ポインタを参照するだけのバッファを作成するはずがないと思います。

(**無効)(void *型)のオブジェクト==

が、私はそれRIIDがアクセス違反をのtypedefであるREFID(される原因となっているここで重要な問題を考えて参照オブジェクトとしてinterperatedすることができますIID *)ので、を参照のGuid

のPInvokeを使用してこれを処理することができるはずであるべき:


     [DllImport("ole32.dll")] 
     public static extern UInt32 StgCreateStorageEx(
      [MarshalAs(UnmanagedType.LPWStr), In] string pwcsName, 
      int grfMode, 
      int stgfmt, 
      uint grfAttrs, 
      [In] IntPtr pStgOptions, 
      [In] IntPtr reserved2, 
      [In] ref Guid riid, 
      [MarshalAs(UnmanagedType.IUnknown), Out] out object ppObjectOpen); 
+0

私は "object ppObjectOpen;"と宣言します。それを最後のパラメータとして渡しますか?私はまだこのようにアクセス違反をしています。この小さなコメントボックスから抜け出す方法を決めることができたら、修正されたコードを投稿します。 –

+0

メソッドのシグネチャを修正しましたが、grfModeはintでなくてはなりません。 –

+0

stgfmtとgrfmodeをenumsで置き換えることができます。enumの型がintであることを確認してください。 –

関連する問題