views:

145

answers:

0

I have spent numerous hours searching and experimenting, but I have not been able to accomplish full interoperability between C# and Borland C++ Builder 6 (notably in handling events in a C++ application that are raised by the C# COM object).

I have been able to make calls to a COM object from the C++ application, but I have not been able to handle events.

I have successfully gotten event handling working (via an event sink) between VC++ and COM, thanks to codeproject

I have not been able to recreate this in C++ Builder 6.

Does anybody have any examples of this?

[Edit]

Sorry for the vague question. I will layout what I have gotten so far.

Using a sample I found, I have the following ManagedMusic namespace:

using System;
using System.Runtime.InteropServices;

namespace ManagedMusic
{
  public delegate void Stopped_EventHandler(byte songTitle, byte time);    

  [Guid("285C5024-2E30-4089-AE2D-90A62F2107DE")]
  [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
  public interface IMusicEvents
  {
      void Stopped(byte songTitle, byte time);
  }

  [Guid("0CDD4767-A776-49ad-97BA-225BAD074E16")]
  public interface IMusic
  {
      byte Play(byte songTitle, byte notify);

      byte GetSongTitle();

      void SetSongTitle(byte b);
  }

  [Guid("6F6C45D9-E259-48ad-B35E-DFC218DB559B"),
  ClassInterface(ClassInterfaceType.None),
  ComSourceInterfaces(typeof(ManagedMusic.IMusicEvents))]
  public class Music : IMusic
  {
      private byte m_songTitle;

      public event Stopped_EventHandler Stopped;

      public Music()
      {
          this.m_songTitle = 0;
      }

      public byte GetSongTitle()
      {
          return m_songTitle;
      }

      public void SetSongTitle(byte b)
      {
          this.m_songTitle = b;
      }

      public byte Play(byte songTitle, byte notify)
      {              
          this.m_songTitle = songTitle;
          if(notify == 1)
          {
              Stopped(this.m_songTitle, 200);
          }
          return 123;
      }

  }
}

I have the correct settings (register type lib after build in project settings, et al).

I have created a new C++ package named MusicPackage and imported the ManagedMusic typelib.

The C++ Builder generated the imports ManagedMusic_TLB (.h and .cpp files) and ManagedMusic_OCX (.h and .cpp files), which include the event sink.

I have created a MusicClient project in C++ builder. It contains a form, a button, and a textbox to show a SongTitle (set by pressing the button).

The button handler code looks like this:

void __fastcall TfrmMusic::btnPlayClick(TObject *Sender)
{
  myMusic->Play(1, 0);
  txtSongTitle->Text = myMusic->GetSongTitle();

  ShowMessage("Should see a 1 in the textbox");

  ShowMessage("Should get an error now because an event is being raised.");

  myMusic->Play(1, 1);  //Sets the SongTitle and also raises an event.  - Error is here
}

The COM Event handler code is:

void __fastcall TfrmMusic::myMusicStopped(TObject *Sender,
      unsigned_char songTitle, unsigned_char time)
{
    ShowMessage("Receive an event.");
}

The error is 'this->Play(songTitle, notify, (unsigned_char*)&pRetVal)': Not implemented @ ManagedMusic_TLB.h/164

The code is (generated file ManagedMusic_TLB.h)

unsigned_char __fastcall Play(unsigned_char songTitle/*[in]*/, unsigned_char notify/*[in]*/)
{
  unsigned_char pRetVal;
  OLECHECK(this->Play(songTitle, notify, (unsigned_char*)&pRetVal));   <--- Line 164
  return pRetVal;
}

The return value of this-Play . . . is -2147467263 (0x8004001)

Has anybody successfully handled events raised by a C# COM object in Borland C++?