问题描述
我的问题和这两个很相似:
My question is very similar to these two:
C# 组件事件?
C# - 编写 COM 服务器 - 事件不在客户端触发
但是,对他们有效的方法对我无效.类型库文件没有任何事件定义的提示,所以 Delphi 看不到它.如您所料,该类适用于其他 C# 应用程序.
However, what worked for them is not working for me. The type library file, does not have any hints of events definitions, so Delphi doesn't see it. The class works fine for other C# applications, as you would expect.
COM 服务器工具:
- Visual Studio 2010
- .NET 4.0
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 应用程序可以很好地查看和使用任何属性、方法和函数.它只是看不到事件.
The type library file has the definitions for the properties and methods, but no events are visible. I even opened the type library in Delphi's viewer to make sure. The Delphi app can see and use any property, methods, and functions just fine. It just doesn't see the events.
如果有任何建议或文章可供阅读,我将不胜感激.
I would appreciate any pointers or articles to read.
谢谢!
推荐答案
经过反复试验,我终于解决了这个问题.我需要对 C# 代码进行两处更改.
I finally got this resolved after much trial and error. There were 2 things that I needed to change on the C# code.
1) [ClassInterface(ClassInterfaceType.None)] 需要更改为 [ClassInterface(ClassInterfaceType.AutoDual)]
1) [ClassInterface(ClassInterfaceType.None)] needed to be changed to [ClassInterface(ClassInterfaceType.AutoDual)]
2) 作为事件源的类需要从 MarshalByRefObject 继承.如果在源类中完成了任何线程,这会有所帮助.
2) The class that is the source of the events needs to inherit from MarshalByRefObject. This helps if there is any threading done in the source class.
我只需要在 Delphi 方面做一件事.我需要确保选中生成组件包装器"复选框.这就是在 Delphi 方面实际构建事件脚手架的原因.
I only needed one thing on the Delphi side. I needed to make sure to have the "Generate Component Wrapper" checkbox checked. This is what will actually build the event scaffolding on Delphi's side.
这就是你在 Delphi 7 中的做法:
This is how you do it in Delphi 7:
- 从菜单项目中选择 -> 导入类型库
- 确保选中生成组件包装器"
- 从列表中选择 COM 类
- 点击添加单元"按钮
新单元将具有您的 COM 事件的定义.
The new unit will have the definitions of your COM events.
关于如何做到这一点的分步博客文章
这篇关于向 Delphi 客户端应用程序公开 C# COM 服务器事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!