近一个星期以来,我一直试图弄清楚如何在 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。