Komunikator: komunikacja między programem a pluginem

0

Witam!

Na poczatku Paździenika wpadliśmy z qmplem na pomysł stworzenia komunikatora internetowego. miałby on się opierać na mechaniźmie wtyczek - czyli program główny - wtyczki do obsługi protokołów komunikacyjnych. Zassałem ze strony EKG specyfikację protokołu GG (tak na początek), przestudiowałem ją dogłębnie, przeprowadziłem wiele testów (pomyślnych :) ) i zabrałem sie za prace nad programem. Stworzylismy wstępne GUI http://members.lycos.co.uk/kgsoft/mkontakt/mkontakt_alpha.JPG (jeśli nie działa to: http://members.lycos.co.uk/kgsoft/mkontakt/mkontakt_alpha.jpg) i zabraliśmy się za główny "silnik" programu.

I mam pytanie w sprawie opcji pluginu. A mianowicie w jaki najlepszy sposób program główny mógłby się wymieniać ustawieniami, żeby nie trzeba było korzystać ze sposobu:

Program główny zapisuje do pliku - plugin odczytuje te dane i na odwrót (przyznam że to dość prostacki pomysł, ale żaden mi nie przychodzi do głowy).

Dziękuję z góry za wszelkie odpowiedzi i proszę o uwagi odnośnie mojego pomysłu.
//Pozdro 4all programmers

//dopisane: najwazniejsze chyba: program pisze w języku c++

0

A pod jaki system? :P

0

Pod Windows'a - na Linuksa nie pisałem jeszcze niczego "dużego"

0

Pluginy w dll, to chyba najprostsze rozwiązanie :)

0

Pluginy w dll, to chyba najprostsze rozwiązanie

No przecież robię w dll, tylko mi chodzi o to w jaki sposób program ma przekazywać pluginowi na raz wiele opcji np.: uid, hasło, serwer, port, lub np. przy wysyłaniu wiadomości musi być: uid lub jakiś login, treść, data i jakieś dodatkowe informacje.Albo gdy user otrzyma wiadomośc to plugin musi jakoś powiadomić program o wiadaomości i ją mu w odpowiedniej formie "dostarczyć" I właśnie jak zrobić takie uniwersalne rozwiązanie, dzięki któremu można byłoby transportowac międy pluginem a programem i na odwórt naraz wiele informacji różnego typu: char, int, short itp, itd.

0

wysyłaj/zwracaj pointery do struktur gdzie pierwszy parametr to wielkość/typ struktury

0

Też myśłałem o czymś takim. Pozostaję jeszcze kwestia powiadamiania programu o otrzymaniu pakietu przez plugin, no bo chyba dll nie moze wywołac funkcji z programu (chyba ze zna adres i prototyp funkcji-moge sie myslić). Myslałem o czyms takim:
-wątek "komunikacyjny" pluginu otrzymuje pakiet z serwera, sprawdza go i jeśli jest poprawny to wysyła do okna programu komunikat.

  • program w odpowiedzi na komunikat i w zależności od parametrów wparam i lparam wywołuje z dll jakąs tam funkcję (podając jako parametr pointer do jakiejś struktury) aby pobrac te dane.

Ale to chyba nie najlepszy pomysł bo taki komunikat może wysłać dowolny program i wtedy co?

0

Widze, ze nie dostales zbyt ciekawych odpowiedzi, wiec napisalem cos co powinno pomoc ci ogarnac twoj problem.

//plugin
typedef struct //inicjalizacja plugina //connect
{
	GUID	ID;
	char	serv[128];
	char	pswd[128];
	int		port;
	//...
}TInitData;

typedef struct //wiadomosc wysylana
{
	GUID	IDto;
	GUID	IDfrom;
	char	msg[256];
	//...
}TMsgData;

typedef struct //komunikat powiadomienia
{
	int		ID;
	int		size;
	int		flags;
	void	*pData;
}TNotifyData;

//typ powiadomienia
enum NotifyID
{
	REC_MESS =0,
	USER_QUIT,
	USER_ENABLED,
	USER_STATUS_CHANGE
	//...
};

//aby wszystkie implementacje funkcji notify (callbackowe), mozna bylo zamknac w klasach
class CNotify {};

typedef struct
{
	CNotify* notObj;
	int (CNotify::*notFunc)(TNotifyData *pData);
}TNotify;

class CPlugin
{
public:
	CPlugin(){};
	virtual ~CPlugin(){};

protected:

	virtual void SetNotifyFunc(TNotify Notify) = 0;

	virtual bool Connect(TInitData *pData) = 0;
	virtual bool Disconnect(/*...*/) = 0;

	virtual bool SendMess(TMsgData* pData) = 0;

	TNotify	m_Notify;
};

class CGGPlugin : public CPlugin
{
public:
	CGGPlugin(){};
	virtual ~CGGPlugin(){};
	void SetNotifyFunc(TNotify Notify){
		m_Notify = Notify;
	}

	//implementacje zalezne od rodzaju plugina
	bool Connect(TInitData *pData);
	bool Disconnect(/*...*/);
	bool SendMess(TMsgData* pData);
};

powyzsze bedziesz mial w dll, teraz ja sobie wczytujesz i uzyce tego jest takie:

class CController : public CNotify
{
public:
	int HandleNotify(TNotifyData *pData);
};

//funkcja callbackowa przyjmujaca rozne komunikaty
int CController::HandleNotify(TNotifyData *pData)
{
	switch(pData->ID)
	{
	case REC_MESS: //przyslana wiadomosc 
		{
			TMsgData *pMsg = reinterpret_cast<TMsgData*>(pData->pData);
			// AddTextToWindow(pMsg->IDfrom,pMsg->msg);
			// wyswietlenie jej w okienku lub ine operacje
			// o ktorych plugin nie musi wiedziec
		}
	}
	//case USER_QUIT: uzytkownik wylaczyl klienta
	//case USER_ENABLED: uzytkownik udostepnil sie
	//...
	return 0;
}

//...

CController ctrl;
CPlugin* plug = new CGGPlugin; //tutaj mozesz stworzyc obijetnie jaki chcesz plugin

//ustawienie funkcji callbackowej
TNotify notif; 
notif.notObj = &ctrl;
notif.notFunc = (int (CNotify::*)(TNotifyData*))ctrl.HandleNotify;

plug->SetNotifyFunc(notif);

plug->Connect(0/*...*/);

//w tym czasie do CController::HandleNotify, beda dochodzily rozne komunikaty
//np o prszyslaniu wiadmosci, zmianie statusu uzytkownika, jego rozlaczeniu sie etc.
plug->Disconnect(/*...*/);

a tak powinien wewnetrze nie dzialac plugin:
(np jakis uzytkownik przyslal wiadomosc)

TNotifyData notifyData; 
notifyData.ID = REC_MESS; //typ komunikatu
TMsgData messData;
strcpy(messData.msg,otrzymana_wiadomosc);
notifyData.pData = &messData; //dla typu REC_MESS pData jest wskaznikiem na TMsgData
//wywolanie funkcji callbackowej (zostanie wywlana metoda CController::HandleNotify
(m_Notify.notObj->*m_Notify.notFunc)(&notifyData);

Jest to rozwiazanie bardzo uniwersalne i elastyczne, gdy juz napiszesz HandleNotify, to mozesz pisac ile chcesz i jakie chcesz pluginy roznych protokolow.
To co napisalem wyzej jest bardzo uproszczone, ale dodasz tam co potrzebujesz i rozwiazanie sie sprawdzi. Takim samym sposobem mozesz pisac pluginy GUI i innych!

PS. Chyba troche przesadzilem z dlugoscia postu

0

Dzięki void! Nie musiałeś pisać kodu - chodziło mi bardziej o opis uniwersalnego rozwiązania, ale kod na pewno się przyda. Dostosuję go do swoich potrzeb i zabaczę jak to będzie wyglądało.
A tak przy okazji czy byłby ktoś zainteresowany pisaniem pluginów, jeśli tak to mógłbym udostępnić jakieś SDK, ale to zależy od tego czy projekt wypali czy tak jak np. mój shell - po 3 miesiącach stanął w miejscu z braku czasu...

1 użytkowników online, w tym zalogowanych: 0, gości: 1