2009-08-11 4 views
0

저는 C#에서 StgCreateStorageEx를 호출하는 방법을 거의 일주일 동안 알아 내려고 노력해 왔으며, 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가 나를 이상 속이고하지되었는지를 확인하는 결론에 도달했다 아무도이 엉망진창을 풀고 실제로 작동시키는 방법에 대한 아이디어가 있습니까?

그런데 궁극적 인 목표는 TreeView에서 Windows 탐색기로 폴더를 드래그하여 해당 폴더와 모든 내용을 삭제 한 위치에 쓸 수있게하는 것입니다. catch는 TreeView가 전적으로 데이터베이스에 저장된 파일 시스템을 나타냅니다. 내가 할 수있는 유일한 방법은 IStorage를 전달하는 것이므로 StgCreateStorageEx에 대한 호출이 필요합니다.

+0

당신이 pinvoke.net를 시도? http://pinvoke.net/default.aspx/ole32/StgCreateStorageEx.html에는 사용할 수있는 OLE 구조화 된 저장소 주변에 관리되는 래퍼가 있다고 나와 있습니다. –

+0

그것이 제가 시작한 곳입니다. 내가 말할 수있는 한 System.IO.Packaging은 이미 존재하는 Storages를 사용하는 데 적합하지만 실제로 새 저장소를 만들 수는 없습니다. –

답변

1

StgCreateStorage의 서명 및 문서에서 StgCreateStorage가 작성한 개체에 값을 설정할 수 있도록 포인터를 참조해야한다는 점을 고려하면 버퍼를 작성하지 않아도된다고 생각합니다.

(** 무효) (무효 *) 객체 ==

내가 그 riid가 액세스 위반을위한 형식 정의입니다 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를 열거 형으로 교체 할 수 있으면 열거 형이 int인지 확인하십시오. –

관련 문제