簡體   English   中英

C#中的StgCreateStorageEx提供AccessViolationException

[英]StgCreateStorageEx in C# gives 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,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。

從StgCreateStorage的簽名和文檔中,我認為您不應該為此創建一個緩沖區,只需要引用一個指針,以便StgCreateStorage可以將值設置為所創建的對象。

(void **)可以作為ref對象插入,其中object ==(void *)

我認為這里導致訪問沖突的關鍵問題是riid是REFID,它是(IID *)的typedef,因此應參考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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM