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++?