带有签名 C# 的 ISearchManager2 问题
ISearchManager2 issue with signature C#
我正在尝试在 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 中声明继承的 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
...
}
我正在尝试在 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 中声明继承的 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
...
}