views:

242

answers:

2

My question is very similar to these two:

http://stackoverflow.com/questions/1140984/c-component-events

http://stackoverflow.com/questions/1638372/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:

  • Visual Studio 2010
  • .NET 4.0

Delphi applications:

  • Delphi 2010
  • Delphi 7

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!

+2  A: 

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:

  1. Select from the menu Project -> Import Type Library
  2. Make sure that "Generate Component Wrapper" is checked
  3. Select the COM class from the list
  4. Click on the "Add Unit" button

The new unit will have the definitions of your COM events.

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

hectorsosajr
@hectorsosajr : The link seems broken ; is the article still online somewhere? Thanks a lot!
Romain Verdier
My website died, and the backup did not have that blog post. I'll see if I can recreate the post this weekend.
hectorsosajr
A: 

Hi Hector,

I have the same problem as yours . I've changed my c# code as you suggested . but I don't know how to access my event and add a procedure to it in delphi .

I'll really appreciate it if you could send me your delphi sample code of using your event .

Best Regards, Shilan

I'm writing a blog post with all the info on how to do this. I'll post another comment when I'm done with the blog post.
hectorsosajr
Hi Hector ,Thank you for your respond and I'm looking forward for your blog post .I've write my c# dll for another company to use in their delphi application and I'm really in my dead line to give them the solution to use it , So I'll really appreciate it if in the meanwhile you could give me some hints on this matter.Best Regards,shilan
Ok, the blog post is now live over here: http://www.systemwidgets.com/Blog/tabid/61/articleType/ArticleView/articleId/270/C-COM-server-to-Delphi-COM-clients.aspxFeel free to comment over there, if some parts of it are not clear. :)
hectorsosajr