Я провел много часов в поисках и экспериментах, но мне не удалось добиться полной совместимости между C # и Borland C ++ Builder 6 (особенно при обработке событий в приложении C ++, которые вызываются объектом C # COM).
Мне удалось сделать вызов COM-объекта из приложения C ++, но я не смог обработать события.
Я успешно получил работу обработки событий (через приемник событий) между VC ++ и COM, благодаря codeproject
Мне не удалось воссоздать это в C ++ Builder 6.
У кого-нибудь есть примеры этого?
[Изменить]
Извините за смутный вопрос. Я планирую то, что я получил до сих пор.
Используя образец, который я нашел, у меня есть следующее ManagedMusic
пространство имен:
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;
}
}
}
У меня правильные настройки (зарегистрируйте тип lib после сборки в настройках проекта и т. Д.).
Я создал новый пакет C ++ с именем MusicPackage
и импортировал ManagedMusic
typelib.
C ++ Builder сгенерировал импорт ManagedMusic_TLB (файлы .h и .cpp) и ManagedMusic_OCX (файлы .h и .cpp), которые включают приемник событий.
Я создал проект MusicClient в C ++ builder. Он содержит форму, кнопку и текстовое поле для отображения названия песни (устанавливается нажатием кнопки).
Код обработчика кнопки выглядит следующим образом:
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
}
Код обработчика события COM:
void __fastcall TfrmMusic::myMusicStopped(TObject *Sender,
unsigned_char songTitle, unsigned_char time)
{
ShowMessage("Receive an event.");
}
Ошибка «this-> Play (songTitle, notify, (unsigned_char *) & pRetVal)»: не реализовано @ ManagedMusic_TLB.h / 164
Код (сгенерированный файл 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;
}
Возвращаемое значение this-Play . . .
равно -2147467263 (0x8004001)
Кто-нибудь успешно обрабатывал события, вызванные COM-объектом C # в Borland C ++?