我可以简化未在ComImport中使用的方法签名吗? [英] Can I simplify method signatures I am not using in a ComImport?

查看:51
本文介绍了我可以简化未在ComImport中使用的方法签名吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 IWiaDevMgr2 上调用 GetImageDlg .有很多相当复杂的方法(我没有使用过)引用了许多类型(我也没有使用过).由于找不到自动生成其 ComImport 的TLB或IDL,我希望避免手动翻译所有引用的类型.

I am trying to call GetImageDlg on IWiaDevMgr2. There are a number of quite complicated methods (which I am not using) referencing a number of types (that I am also not using). As I cannot find a TLB or an IDL from which to automatically generate my ComImport, I would prefer to avoid having to manually translate all of the referenced types.

我可以通过代替来跳过"方法和类型

Can I "skip" methods and types by substituting from

[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);

};

[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);

};

所有似乎都可以正常工作,而且只要我不呼叫任何占位符即可.我可以这样做而没有后果吗?

Everything seems to work fine, and as long as I don't call any of the placeholders. Can I do this without consequences?

推荐答案

当然可以.您是唯一将使用此接口定义的人,这很好.

Sure you can do this. You're the only one who will be using this interface definition, so that's fine.

当然,如果将此接口用作从本机到托管的回调,则将是一个问题,但是在这种情况下,您将以某种方式实现它.实现这样的虚拟方法是未来问题的征兆.

Of course, if this interface was used as a callback from native to managed, it would be a problem, but in this case you would be implementing it somehow. Implementing such dummy methods is a sign of future problems.

请注意,有一种正式的方法.您可以为占位符使用特殊的 _VtblGap {0} _ {1} 名称,其中0是索引,而1是您要跳过的方法数.

Note there's an official way of doing it. You can use a special _VtblGap{0}_{1} name for the placeholder, where 0 is an index, and 1 is the number of methods you want to skip.

在此处查看Roslyn中的实现(它也在Common Language Infrastructure规范中):

See the implementation in Roslyn here (it's also in the Common Language Infrastructure specification): 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
        // ----------------------

因此,您的情况应该是:

So in your case, it would be:

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

    ...
};

这篇关于我可以简化未在ComImport中使用的方法签名吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆