2017-11-30 24 views
0

IWiaDevMgr2GetImageDlg으로 전화하려고합니다. (내가 사용하지 않고있는) 여러 가지 유형을 참조하는 아주 복잡한 방법이 많이 있습니다. ComImport을 자동으로 생성 할 TLB 또는 IDL을 찾을 수 없으므로 참조 된 모든 유형을 수동으로 번역하지 않아도됩니다.ComImport에서 사용하지 않는 메소드 서명을 단순화 할 수 있습니까?

나는만큼 내가 중 하나를 호출하지 않는 한하고, 잘 작동하는 보인다

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("79C07CF1-CBDD-41ee-8EC3-F00080CADA7A")] 
public interface IWiaDevMgr2_Fake 
{ 
    void VTablePlaceholder0(); 
    void VTablePlaceholder1(); 
    void VTablePlaceholder2(); 
    void VTablePlaceholder3(); 
    void VTablePlaceholder4(); 
    void VTablePlaceholder5(); 
    void VTablePlaceholder6(); 

    [return: MarshalAs(UnmanagedType.Interface)] 
    object GetImageDlg(
     int lFlags, 
     [MarshalAs(UnmanagedType.BStr)] string bstrDeviceID, 
     IntPtr IntPtrParent, 
     [MarshalAs(UnmanagedType.BStr)] string bstrFolderName, 
     [MarshalAs(UnmanagedType.BStr)] string bstrFilename, 
     /* [out] */ out int plNumFiles, 
     /* [size_is][size_is][out] */ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5, ArraySubType = UnmanagedType.BStr)] out string[] ppbstrFilePaths); 

}; 

모두에

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("79C07CF1-CBDD-41ee-8EC3-F00080CADA7A")] 
public interface IWiaDevMgr2 
{ 
    IEnumWIA_DEV_INFO EnumDeviceInfo(
     int lFlags); 

    IWiaItem2 CreateDevice(
     int lFlags, 
     [MarshalAs(UnmanagedType.BStr)] string bstrDeviceID); 

    // ...snip five other method declarations... 

    IWiaItem2 GetImageDlg(
     int lFlags, 
     [MarshalAs(UnmanagedType.BStr)] string bstrDeviceID, 
     IntPtr IntPtrParent, 
     [MarshalAs(UnmanagedType.BStr)] string bstrFolderName, 
     [MarshalAs(UnmanagedType.BStr)] string bstrFilename, 
     /* [out] */ out int plNumFiles, 
     /* [size_is][size_is][out] */ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5, ArraySubType = UnmanagedType.BStr)] out string[] ppbstrFilePaths); 

}; 

에서 대체하여 방법과 유형 "건너 뛰기"수 자리 표시 자. 결과없이이 작업을 수행 할 수 있습니까?

답변

1

물론 가능합니다. 당신은이 인터페이스 정의를 사용할 유일한 사람입니다. 그렇습니다.

물론이 인터페이스가 콜백에서 native에서 managed로 사용 된 경우 문제가 될 수 있지만이 경우 어떻게 든 구현해야합니다. 이러한 더미 메서드를 구현하는 것은 향후 문제의 징후입니다.

참고로 공식적인 방법이 있습니다. 자리 표시 자에 대해 특수한 _VtblGap{0}_{1} 이름을 사용할 수 있습니다. 여기서 0은 색인이고 1은 건너 뛸 메서드의 수입니다.

(는 공용 언어 인프라 사양도입니다) 여기 로슬린의 구현을 참조 : 경우에 따라서 https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/Portable/MetadataReader/ModuleExtensions.cs

 // From IMetaDataEmit::DefineMethod documentation (http://msdn.microsoft.com/en-us/library/ms230861(VS.100).aspx) 
     // ---------------------- 
     // In the case where one or more slots need to be skipped, such as to preserve parity with a COM interface layout, 
     // a dummy method is defined to take up the slot or slots in the v-table; set the dwMethodFlags to the mdRTSpecialName 
     // value of the CorMethodAttr enumeration and specify the name as: 
     // 
     // _VtblGap<SequenceNumber><_CountOfSlots> 
     // 
     // where SequenceNumber is the sequence number of the method and CountOfSlots is the number of slots to skip in the v-table. 
     // If CountOfSlots is omitted, 1 is assumed. 
     // ---------------------- 
     // 
     // From "Partition II Metadata.doc" 
     // ---------------------- 
     // For COM Interop, an additional class of method names are permitted: 
     // _VtblGap<SequenceNumber><_CountOfSlots> 
     // where <SequenceNumber> and <CountOfSlots> are decimal numbers 
     // ---------------------- 

를, 그것은 다음과 같습니다

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("79C07CF1-CBDD-41ee-8EC3-F00080CADA7A")] 
public interface IWiaDevMgr2_Fake 
{ 
    void _VtblGap1_7(); // skip seven methods 

    ... 
};