![](/img/trans.png)
[英]c# struct to IntPtr gives System.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.