【问题标题】:ISearchManager2 issue with signature C#签名 C# 的 ISearchManager2 问题
【发布时间】:2019-08-04 08:53:44
【问题描述】:

我正在尝试在 C# 上加载 ISearchManager2 接口。

到目前为止,ISearchManager 一切正常。我使用 Microsoft.Search.Interop 程序集来做到这一点。 我可以设置目录,从索引器和其他东西中获取一些结果。

但是,现在,我想要名为ISearchManager2 的接口,所以,我创建了:

[ComConversionLoss]
[ComImport]
[Guid("DBAB3F73-DB19-4A79-BFC0-A61A93886DDF")]
[InterfaceType(1)]
public interface ISearchManager2 : ISearchManager
{
    void CreateCatalog([MarshalAs(UnmanagedType.LPWStr)] [In] string pszCatalog, out ISearchCatalogManager _out);
    void DeleteCatalog([MarshalAs(UnmanagedType.LPWStr)] string pszCatalog);
}

来自searchapi.h的相同签名和订单是:

MIDL_INTERFACE("DBAB3F73-DB19-4A79-BFC0-A61A93886DDF")
ISearchManager2 : public ISearchManager
{
public:
    virtual HRESULT STDMETHODCALLTYPE CreateCatalog( 
        /* [string][in] */ __RPC__in_string LPCWSTR pszCatalog,
        /* [out] */ __RPC__deref_out_opt ISearchCatalogManager **ppCatalogManager) = 0;

    virtual HRESULT STDMETHODCALLTYPE DeleteCatalog( 
        /* [string][in] */ __RPC__in_string LPCWSTR pszCatalog) = 0;
};

使用有效的ISearchManager 我正在投射:

ISearchCatalogManager _out;
Teste _test = (Teste)_searchManager;
_test.CreateCatalog(catalog, out _out);

QueryInterface 没有错误(这意味着找到了接口)并且没有异常(带有 hresults)。但是,它从未分配过。调试它,我可以看到 string catalog 发生变化。

[

这是在致电CreateCatalog 之前。之后:

[

我假设它使用一个额外的参数调用 C#,而第二个(输出值)是字符串。 我尝试了PreserveSigAttribute 和其他类似的东西:

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void CreateCatalog([MarshalAs(UnmanagedType.LPWStr)] [In] string pszCatalog, out ISearchCatalogManager _out);

因为当我从ISearchManager(来自Microsoft.Search.Interop)反编译接口时,我可以在函数GetCatalog 上看到具有相同签名的属性。

有人知道为什么会这样吗?

【问题讨论】:

  • 在 .NET 中,您需要在派生接口 (ISearchManager2) 声明中重新声明所有派生 COM 接口 (ISearchManager) 成员(即使您使用 C/C++ 时看起来很奇怪)。 stackoverflow.com/questions/1863128/…
  • 谢谢@SimonMourier。那个概念不在我的脑海里。我必须把 new 关键字放在每个函数上?压制警告。使用和不使用新的。您可以发帖作为回复,我会接受!

标签: c# com signature


【解决方案1】:

在 .NET 中声明继承的 COM 接口时,您必须递归地声明所有继承的接口成员。因此,例如,如果您将其作为基本接口:

[Guid("2cd90691-12e2-11dc-9fed-001143a055f9"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IBase
{
    int Blabla();
}

那么IDerived 的定义会是这样的:

[Guid("65019f75-8da2-497c-b32c-dfa34e48ede6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDerived
{
    // IBase methods
    int Blabla();

    // IDerived methods
    ...
}

或者更好,像这样,如果你想在 .NET 中保持继承层次:

[Guid("65019f75-8da2-497c-b32c-dfa34e48ede6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDerived : IBase
{
    // IBase methods
    new int Blabla();

    // IDerived methods
    ...
}

【讨论】:

    猜你喜欢
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 2017-09-07
    • 2014-07-05
    • 2017-08-25
    • 1970-01-01
    • 2013-04-09
    相关资源
    最近更新 更多