Reputation: 4250
My question is very similar to these two:
C# - writing a COM server - events not firing on client
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 Server tools:
Delphi applications:
Here's a simplified version of the code:
/// <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");
}
}
}
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.
Thanks!
Upvotes: 4
Views: 4236
Reputation: 4250
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)] needed to be changed to [ClassInterface(ClassInterfaceType.AutoDual)]
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.
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.
This is how you do it in Delphi 7:
The new unit will have the definitions of your COM events.
Step-By-Step blog post on how to do this
Upvotes: 5