Skocz do zawartości


Zdjęcie

Używanie SDK w wątkach

aqq sdk wątki dll c++ builder

  • Zaloguj się, aby dodać odpowiedź
13 odpowiedzi w tym temacie

#1 Sauler

Sauler

    Bywalec

  • Użytkownik
  • 210 postów

Napisano 2016.02.07, 21:43

Witam,

Mimo, że AQQ jest praktycznie trupem to lubię czasem wieczorem posiedzieć i coś napisać  :-P

 

A więc mój problem polega na używaniu SDK w wątku, np. odbierającym wiadomości. Gdy tworzę funkcję bez parametrów, która zajmuje się wysłaniem wiadomości do AQQ i wywołuję ją z użyciem Synchronize to nic się nie dzieje. Oczywiście znalazłem powód dlaczego tak się dzieje, otóż AQQ i moja dllka mają osobne listy synchronizacji, więc użycie funkcji Synchronize odpada. Sekcją krytyczną też próbowałem, ten sam efekt. A po wywołaniu funkcji bez synchronizacji AQQ pokazuje informację o wiadomości i się zawiesza.

 

Przejdźmy więc do pytania: Jak używać SDK w wątkach?

 

Spoiler
 



#2 Oconnel

Oconnel

    AQQ Developer

  • Właściciel
  • 4622 postów

Napisano 2016.02.08, 11:11

Nie wszystkich funkcji możesz używać na wątkach ponieważ kontrolka IE nie jest thread-safe. Jeżeli AQQ się zawiesza to prawdopodobnie nie możesz uzyskać tego czego oczekujesz. Wówczas korzystaj z synchronize - jeżeli "nic się nie dzieje" to znaczy - że robisz coś źle. A co? Kto wie. Trzeba by przeanalizować kod.


MyPortalYouTubeTwitter54slty.png

#3 Sauler

Sauler

    Bywalec

  • Użytkownik
  • 210 postów

Napisano 2016.02.08, 12:57

Kawałek kodu z odbieraniem wiadomości. Znajduje się on w pętli odbierającej zdarzenia, która znajduje się w wątku:

if (event->type == GG_EVENT_MSG) {
    ZeroMemory(&msg, sizeof(TPluginMessage));
    msg.cbSize = sizeof(TPluginMessage);
    msg.JID = UnicodeString(UIntToStr(event->event.msg.sender) + "@plugin.gg.pl").w_str();
    ShowMessage(msg.JID);
    msg.Date = Now();
    msg.ChatState = CHAT_NONE;
    char *b = (char*) event->event.msg.message;
    AnsiString Body(b);
    UnicodeString UBody(Body);
    msg.Body = UBody.w_str();
    ShowMessage(msg.Body);
    msg.Offline = false;
    msg.DefaultNick = UIntToStr(event->event.msg.sender).w_str();
    ShowMessage(msg.DefaultNick);
    msg.Store = true;
    msg.Kind = MSGKIND_CHAT;
    if (event->event.msg.sender != 0) {
        //TODO: MESSAGE
        Synchronize(SendMessageToAQQ);
    }
}

Funkcja SendMessageToAQQ:

void __fastcall TEventThread::SendMessageToAQQ() {
    ShowMessage("5");
    PluginLink.CallService(AQQ_CONTACTS_MESSAGE, 0, (LPARAM)(&msg));
    ShowMessage("6");
}

Zmienna msg jest zadeklarowana jako prywatna zmienna w klasie TEventThread:

TPluginMessage msg;

I teraz powiedz mi co tutaj jest źle. 



#4 Oconnel

Oconnel

    AQQ Developer

  • Właściciel
  • 4622 postów

Napisano 2016.02.08, 14:14

Wyświetla ci się 5 i 6?


MyPortalYouTubeTwitter54slty.png

#5 Sauler

Sauler

    Bywalec

  • Użytkownik
  • 210 postów

Napisano 2016.02.08, 14:33

Nie.



#6 Oconnel

Oconnel

    AQQ Developer

  • Właściciel
  • 4622 postów

Napisano 2016.02.08, 17:49

Zauważ, że 5 powinno wyświetlić się zanim zostanie wywołana instrukcja w AQQ. Zatem to nie jest problem po stronie komunikatora a po stronie Twojego kodu. Może ktoś z większą znajomością C++ ci tutaj pomoże bardziej niż ja.  Generalnie musisz też pamiętać że pliki DLL to nie są pliki wykonywalne i jako takie nie posiadają pętli zdarzeń co może być też przyczyną dlaczego ci ten kod nie działa. Poszperaj i poszukaj jakiś przykładów. W necie jest tego pełno dla Delphi to będzie i dla C++.


MyPortalYouTubeTwitter54slty.png

#7 Sauler

Sauler

    Bywalec

  • Użytkownik
  • 210 postów

Napisano 2016.02.08, 17:52

Myślisz, że nie szukałem? We wtyczce GG masz po prostu Synchronize? Bo mam jedną wtyczkę w delphi, która też korzysta z wątków i Synchronize też nie działa.



#8 Oconnel

Oconnel

    AQQ Developer

  • Właściciel
  • 4622 postów

Napisano 2016.02.08, 18:00

Ja nie wywołuję nic na wątkach we wtyczce GG. Bo nie ma takiej potrzeby. Generalnie jestem praktycznie pewien, że nie można używać Synchronize w DLLkach. Tak jak pisałem wcześniej Synch wymaga message-queue którego DLL-ka po prostu nie ma. Stąd zwiecha.

 

Musisz jakoś wydzielić CallService i wywołać to w obrębie wątku głównego. Wtedy zadziała.

 

EDIT:

Jedyna opcja jaką widzę to użycie callback-u. Znajdź sobie jakiś przykład lepszy niż ten:

http://stackoverflow...d-to-comunicate


MyPortalYouTubeTwitter54slty.png

#9 Sauler

Sauler

    Bywalec

  • Użytkownik
  • 210 postów

Napisano 2016.02.08, 20:32

To, że nie można to już wyczytałem dawno, ale jakoś rozwiązania nie mogę znaleźć. Ale jeszcze będę szukał ;)

 

Edit: Spróbuję to ogarnąć sygnałami: http://en.cppreferen.../program/signal ale później bo teraz wychodzę.

Edit2: To rozwiązanie niestety nie działa.


Jakoś się udało :D:D


Użytkownik Sauler edytował ten post 2016.02.08, 19:02

  • Beherit lubi to

#10 Oconnel

Oconnel

    AQQ Developer

  • Właściciel
  • 4622 postów

Napisano 2016.02.08, 21:51

No i lux.


MyPortalYouTubeTwitter54slty.png

#11 Sauler

Sauler

    Bywalec

  • Użytkownik
  • 210 postów

Napisano 2016.02.08, 22:04

Ale pisanie tej wtyczki to będzie koszmar  :wrr:



#12 Oconnel

Oconnel

    AQQ Developer

  • Właściciel
  • 4622 postów

Napisano 2016.02.09, 09:09

Zasady pisania bibliotek DLL są jakie są i nie AQQ jest tu za coś odpowiedzialne :D


MyPortalYouTubeTwitter54slty.png

#13 Sauler

Sauler

    Bywalec

  • Użytkownik
  • 210 postów

Napisano 2016.02.09, 10:22

Ale ja nie mówię, że będzie trudno przez DLLkę czy tam AQQ. Będzie trudno, bo chcę to zaimplementować podobnie jak jest w Kadu  xD



#14 Beherit

Beherit

    In Sorte Diaboli

  • Wtyczkopisarz
  • 5031 postów

Napisano 2016.02.09, 18:54

To, że są takie problemy jest winą AQQ - w konkurencyjnym komunikatorze nie ma problemów z wątkami.







Również z jednym lub większą ilością słów kluczowych: aqq, sdk, wątki, dll, c++, builder

Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych