代码之家  ›  专栏  ›  技术社区  ›  Hector Sosa Jr

向Delphi客户机应用程序公开C COM服务器事件

  •  4
  • Hector Sosa Jr  · 技术社区  · 16 年前

    我的问题与这两个问题非常相似:

    C# component events?

    C# - writing a COM server - events not firing on client

    然而,为他们工作的并不适合我。类型库文件没有任何事件定义的提示,因此Delphi看不到它。如您所料,该类对于其他C应用程序也可以正常工作。

    COM服务器工具:

    • Visual Studio 2010
    • .NET 4

    Delphi应用程序:

    • 德尔福2010
    • 德尔福7

    下面是代码的简化版本:

     /// <summary>
    /// Call has arrived delegate.
    /// </summary>
    [ComVisible(false)]
    public delegate void CallArrived(object sender, string callData);
    
    /// <summary>
    /// Interface to expose SimpleAgent events to COM
    /// </summary>
    [ComVisible(true)]
    [GuidAttribute("1FFBFF09-3AF0-4F06-998D-7F4B6CB978DD")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IAgentEvents
    {
        ///<summary>
        /// Handles incoming calls from the predictive manager.
        ///</summary>
        ///<param name="sender">The class that initiated this event</param>
        ///<param name="callData">The data associated with the incoming call.</param>
        [DispId(1)]
        void OnCallArrived(object sender, string callData);
    }
    
    /// <summary>
    /// Represents the agent side of the system. This is usually related to UI interactions.
    /// </summary>
    [ComVisible(true)]
    [GuidAttribute("EF00685F-1C14-4D05-9EFA-538B3137D86C")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComSourceInterfaces(typeof(IAgentEvents))]
    public class SimpleAgent
    {
        /// <summary>
        /// Occurs when a call arrives.
        /// </summary>
        public event CallArrived OnCallArrived;
    
        public SimpleAgent() {}
    
        public string AgentName { get; set; }
    
        public string CurrentPhoneNumber { get; set; }
    
        public void FireOffCall()
        {
            if (OnCallArrived != null)
            {
                OnCallArrived(this, "555-123-4567");
            }
        }
    }
    

    类型库文件具有属性和方法的定义,但没有可见的事件。我甚至在Delphi的查看器中打开了类型库来确保这一点。Delphi应用程序可以查看和使用任何属性、方法和函数。只是看不到事件。

    我会感谢你的任何建议或文章。

    谢谢!

    1 回复  |  直到 11 年前
        1
  •  5
  •   Hector Sosa Jr    15 年前

    经过反复试验,我终于解决了这个问题。有两件事我需要改变C代码。

    1)[ClassInterface(ClassInterfaceType.None)]需要更改为[ClassInterface(ClassInterfaceType.AutoDual)]

    2)作为事件源的类需要从MarshalByRefObject继承。这有助于在源类中执行任何线程。

    我只需要德尔福方面的一件事。我需要确保选中“生成组件包装器”复选框。这就是将在Delphi方面实际构建事件脚手架的原因。

    在Delphi7中是这样做的:

    1. 从菜单“项目”->导入类型库中选择
    2. 确保选中“生成组件包装器”
    3. 从列表中选择COM类
    4. 点击“添加单元”按钮

    新单元将具有COM事件的定义。

    Step-By-Step blog post on how to do this