0

私はほぼ 1 週間、C# で StgCreateStorageEx を呼び出す方法を理解しようとしてきました。

関数をどのように宣言すればよいかさえわかりません。無数のウェブサイトが無数の異なる方法でそれを宣言しているのを見てきました。しかし、これは私が現在持っているものです:

[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、Interface、LPStruct、およびその他のいくつかを使用してみました。唯一気になったのは、マーシャラーがデータ型に不満を持っていたことです。関係ありそうな気もするけど、いらないことしか言わないから、なにがしたいのかわからない。

関数の呼び出し方法について: これは最初はずっと簡単でした。しかし、メモリ違反が発生した後、私は読み始め、最終的にGCが私を台無しにしていないことを確認する唯一の方法は自分でメモリを管理することであるという結論に達しました。

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());

この混乱を正し、実際に機能させる方法について誰かアイデアを持っていますか?

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

4

1 に答える 1

1

StgCreateStorage の署名とドキュメントから、そのようなバッファを作成することになっているとは思いません. StgCreateStorage が作成されたオブジェクトに値を設定できるようにするには、ポインタへの参照が必要です。

(void**) は、オブジェクト == (void*) である ref オブジェクトとして解釈できます。

ここでアクセス違反を引き起こしている主な問題は、 riid が (IID*) の typedef である REFID であるため、ref 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);
于 2009-08-11T20:29:50.623 に答える