【问题标题】:How to declare Classic COM Interface IBindCtx in C#?如何在 C# 中声明经典 COM 接口 IBindCtx?
【发布时间】:2017-08-22 05:29:53
【问题描述】:

我目前正在研究 C# 和 COM 接口。 C# 中的 COM 文档很少,因为 C# 出现在 COM 之后(也许我们 SO 可以修复)。我发现了the C# compiler can give informative error messages。可以从错误消息中读取方法签名的 C# 语法版本,然后添加到您的类中。这适用于 IAdviseSink,但不适用于 IBindCtx。

最后一个方法RevokeObjectParam(string a) 出现错误,C++ 中的语法是HRESULT RevokeObjectParam( [in] LPOLESTR pszKey );LPOLESTR 是一个空终止的基于 2 字节的字符串,因此使用 [MarshalAs(UnmanagedType.LPWStr)] 应该可以工作。但它没有,我收到错误消息

     * Class1.cs(25,14,25,40): error CS0539: 'IBindCtx.RevokeObjectParam' in explicit interface declaration is not a member of interface
     * Class1.cs(6,18,6,24): error CS0535: 'ComInterfacesInCSharp.Class1' does not implement interface member 'System.Runtime.InteropServices.ComTypes.IBindCtx.RevokeObjectParam(string)'

那么我该如何修改这个方法签名来修复呢?可复制到 Visual Studio 的完整代码如下(创建一个类库项目)。

using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;

namespace ComInterfacesInCSharp
{
    public class Class1 : System.Runtime.InteropServices.ComTypes.IBindCtx 
    {
        void IBindCtx.RegisterObjectBound(object obj) { }
        void IBindCtx.RevokeObjectBound(object obj) { }
        void IBindCtx.ReleaseBoundObjects() { }
        void IBindCtx.SetBindOptions(ref System.Runtime.InteropServices.ComTypes.BIND_OPTS opts) { }
        void IBindCtx.GetBindOptions(ref System.Runtime.InteropServices.ComTypes.BIND_OPTS opts) { }
        void IBindCtx.GetRunningObjectTable(out System.Runtime.InteropServices.ComTypes.IRunningObjectTable tab) { }
        void IBindCtx.RegisterObjectParam(string s, object obj) { }
        void IBindCtx.GetObjectParam(string s, out object obj) { }
        void IBindCtx.EnumObjectParam(out System.Runtime.InteropServices.ComTypes.IEnumString enumString) { }

        /* Problem here https://msdn.microsoft.com/en-us/library/windows/desktop/ms693771(v=vs.85).aspx
         * C++ Syntax is 
         * HRESULT RevokeObjectParam( [in] LPOLESTR pszKey );
         * LPOLESTR is a null terminated 2 byte based string so UnmanagedType.LPWStr ought to work
         * 
         */
        //void IBindCtx.RevokeObjectParam(string a) { }
        void IBindCtx.RevokeObjectParam([MarshalAs(UnmanagedType.LPWStr)] string a) { }

        /*
         * Compile errors are
         * Class1.cs(25,14,25,40): error CS0539: 'IBindCtx.RevokeObjectParam' in explicit interface declaration is not a member of interface
         * Class1.cs(6,18,6,24): error CS0535: 'ComInterfacesInCSharp.Class1' does not implement interface member 'System.Runtime.InteropServices.ComTypes.IBindCtx.RevokeObjectParam(string)'
         */
    }
}

顺便说一句,如果您有一个详细介绍这些 C# 接口的 Web 资源,那就太棒了!

【问题讨论】:

  • 不清楚你在问什么。也就是说,接口方法 RevokeObjectParam 返回一个int。见:IBindCtx
  • @TnTinMn:你给的链接太棒了!它回答了我的问题,什么是正确的方法签名。现在我已经确定来自 Microsoft。

标签: c# c++ com com-interop com-interface


【解决方案1】:

你给的链接太棒了!它回答了我的问题,什么是正确的方法签名。现在我已经明确地来自微软。

虽然您可以从 Microsoft's Reference Source site 找到许多源代码定义,但这并不是您发现程序集中定义的方法的签名的唯一选择。

学习使用Visual Studio's Object Browser。查看菜单->对象资源管理器(或按 F2 键)。

在您实现接口的特定情况下,您可以让 Visual Studio 自动为您实现接口。右键单击接口名称广告选择“实现接口”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-02
    • 2011-02-26
    • 2010-09-24
    • 2016-12-24
    • 1970-01-01
    • 2018-03-30
    • 2018-01-19
    • 1970-01-01
    相关资源
    最近更新 更多