Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
25.05.2009, 11:20
LeJean



Morgen,

ich hab ein etwas spezielleres Problem - aber vielleicht hab ich ja Glück und es gibt hier Leute, die sich schonmal mit der ACE-Library (C/C++) auseinandersetzen durften.

Ich habe eine Klasse, die von ACE_Task_Base erbt und durch Aufruf von activate() einen eigenen Thread startet und die überschriebene Methode svc() aufruft. So weit so gut, das funktioniert. Jetzt hat ACE_Task einen ACE_Thread_Manager dabei, der ja zusätzlich Threads spawnen kann - diese Möglichkeit möchte ich gerne nutzen.

Zuerst mal der relevante Quellcode (gekürzt, Namen geändert da vertraulich)
Quellcode:#include "stdafx.h"
#include "ace/Task.h"

using namespace std;

class ThreadTest : public ACE_Task_Base
{
public:
    virtual int        svc();
    unsigned int    sub_thread(void* args);
};

int ThreadTest::svc()
{
    cout << "Starting sub-thread." << endl;                        // Print status

    // Spawn a new thread by using the ACE_Thread_Manager (thr_mgr_) inherited from ACE_Task_Base
    int group_id =
        this->thr_mgr_->spawn(
            reinterpret_cast<ACE_THR_FUNC>(this->sub_thread),    // Cast method pointer to ACE_THR_FUNC
            //(ACE_THR_FUNC)sub_thread,
            0,                                                    // No arguments
            THR_NEW_LWP                                            // Spawn it as new leightweight process
        );

    return 0;
}

unsigned int sub_thread(void* args)
{
    cout << "Running." << endl;                                    // Print status
}
Der Aufruf findet dann so statt:
Quellcode:ThreadTest tt;
tt.activate();
Mein Problem ist jetzt, dass an der Stelle im ersten Quelltextabschnitt, an der mit nem reinterpret_cast in ACE_THR_FUNC gecastet werden soll ein Fehler vom Compiler geschmissen wird:
Quellcode:error C2440: 'reinterpret_cast' : cannot convert from 'overloaded-function' to 'ACE_THR_FUNC' Okay, ich sehe, dass dort nicht gecastet werden kann. Aber in allen Beispielen, die ich dazu gefunden habe (die im Übrigen recht rar sind - auch auf allen ACE-Tutorial und -Doku Seiten) wird mit nem reinterpret oder wie in der darunter auskommentierten Zeile gecastet. Ähnliche Fehler wie meinen finde ich nicht, davon schreibt niemand.

Ich arbeite hier mit Visual Studio 2008 Professional und habe natürlich auch die ganze ACE-Library entsprechend damit und dafür kompiliert.

Jemand ne Idee?

--

zum Seitenanfang zum Seitenende Profil || Suche
001
25.05.2009, 13:27
J_Hannes



ich hab zwar keine Ahnung was ACE is aber es kann sein das es da probleme giebt weil es sich um eine Methode und nicht um eine Funktion handelt.

versuch mal die sub_thread methode als globale Funktion zu deklarieren und die Objectinstance mitzugeben (so mach ich das immer wenn ich was mit threads mache)

--

Heut' debug ich morgen brows' ich übermorgen cast' ich die Königin auf int
http://doubledtown.myminicity.com/

zum Seitenanfang zum Seitenende Profil || Suche
002
25.05.2009, 13:40
theDon



Wie ist denn ACE_THR_FUNC definiert?

--

\o tanz den naziprau! o/

And more than ever, I hope to never fall,
Where enough is not the same it was before

zum Seitenanfang zum Seitenende Profil || Suche
003
25.05.2009, 13:55
LeJean



ACE_THR_FUNC ist mit ACE_THR_FUNC_INTERNAL weiter beschrieben, und dazu finde ich in den mir zugänglichen Sachen leider keine Informationen. Bzw. es ist eigentlich ein Funktionspointer:
Quellcode:typedef ACE_THR_FUNC_RETURN (*ACE_THR_FUNC)(void *); Also ich möchte gerne komplett in der OO bleiben und nicht mit statischen Funktionen umherwerfen müssen. Wenn ich sie statisch global definiere, funktioniert das problemlos, z.B.:
Quellcode:static void sub_thread() {
    cout << "Running." << endl;
}
Jetzt gerade versuche ich, ob ich mit Funktionspointern auf Memberfunktionen (Methoden) weiter komme. Bisher sieht das noch halbwegs gut aus, aber ich bin noch nicht weit genug um sagen zu können ob es klappt oder nicht.

Danke schonmal!

Editiert: Der Quelltext aus meinem Eröffnungspost hatte eh noch ein paar Macken, der hat sich inzwischen etwas geändert. Ich werd bei nächster Gelegenheit mal den aktuellen Ausschnitt posten.

--


Dieser Beitrag wurde am 25.05.2009 um 13:57 von LeJean bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
004
25.05.2009, 15:07
theDon



http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2

--

\o tanz den naziprau! o/

And more than ever, I hope to never fall,
Where enough is not the same it was before

zum Seitenanfang zum Seitenende Profil || Suche
005
25.05.2009, 18:07
LeJean



Ha.. also mir ist durchaus klar, dass ich Memberfunktionen nicht einfach so aufrufen kann. Ich würde auch nicht auf die Idee kommen, diese Funktion ohne eine zugehörige Instanz aufrufen zu wollen.
Eigentlich war mein Plan aber, das allgemein zu halten, da die entsprechende Methode verschiedener Objekte, die als Thread laufen soll, nicht unbedingt immer gleich heißt. Dafür wollte ich dann eigentlich eine statische Funktion haben, die ich allgemein aus einem Objekt aufrufen kann und als Parameter einen Pointer auf das Objekt und einen Memberfunktionspointer übermittle. So hätte ich die Chance gehabt das alles mit einer statischen Funktion zu regeln. Ist aber irgendwie eher ein unsauberer Workaround..

Quellcode:(objektInstanz.*funktionsPointer)(); wäre übrigens dann ein legitimer Aufruf.

Da ich das Ganze aber wohl etwas exzessiver betreiben muss, werde ich die Architektur entsprechend umstellen und auf noch mehr verschiedene Klassen zurückgreifen, die interagieren und deren Objekte jeweils eigene LWPs bekommen.

Vielen Dank trotz allem für die Mühen ;)

--

zum Seitenanfang zum Seitenende Profil || Suche
006
29.07.2009, 10:51
LeJean



Moin nochmal!

Ich hab die ganze Sache jetzt generell so umgesetzt, dass alles, was ein Thread sein soll auch eine eigene Klasse hat. Hat sicher einige Vorteile und gehört sich vielleicht auch so... aber darum soll's jetzt erstmal nicht mehr gehen.

Meine aktuelle Problematik:
Die ganze Sache läuft auf meinem Entwicklungsrechner völlig unproblematisch. Ich kann aus Visual Studio 2008 die Applikation starten und die Kompilate auch ohne IDE direkt ausführen, egal ob Release oder Debug. Ich nutze keine .NET Komponenten, wenngleich die DLL von ACE (ACE(d).dll) Abhängigkeiten zu msvcm90.dll, msvcp90.dll und msvcr90.dll hat (bzw. deren Debug-Versionen). Ich weiß aber nicht, ob diese Abhängigkeiten wirklich mit .NET zusammenhängen oder allgemein von den VS Compilern kommen. Auch eine Analyse mit depends.exe eröffnet keine weiteren speziellen (unaufgelösten) Abhängigkeiten.
Auch wenn ich von Visual Studio die Abhängigkeiten aufzeigen lassen möchte, werden mir keine weiteren angezeigt.

Führe ich die Applikation jetzt auf einem anderen PC aus, startet die Anwendung zwar ohne Fehlermeldung, jedoch werden die Threads nicht gespawned. Ausgaben, die ausserhalb von Threads gemacht werden, werden angezeigt. Alles was irgendwie in Threads läuft findet schlichtweg nicht statt.

Bei der ganzen Sache ist es egal, ob auf dem Rechner, auf dem die Anwendung ausgeführt werden soll, ACE komplett vorliegt (also auch dort kompiliert wurde) oder nicht. Selbst wenn ich mein Projekt (bzw. die ganze Solution) in einer VS Instanz auf einem anderen Rechner lade, die Pfade in den Projekteinstellungen anpasse und die Applikation starten möchte, werden Threads nicht gestartet.

Hat jemand von euch damit schonmal Probleme gehabt und vielleicht eine Lösung oder einen Ansatz parat? So langsam weiß ich nicht mehr, was ich sonst noch machen sollte.

http://msdn.microsoft.com/de-de/library/8kche8ah.aspx
http://msdn.microsoft.com/de-de/library/ms235265.aspx
http://msdn.microsoft.com/de-de/library/ms235299.aspx
http://msdn.microsoft.com/de-de/library/ms235317.aspx

Diese Quellen haben mir leider nicht weiter geholfen.

Editiert:
Was bestimmt mit den Threads zusammenhängt, sind Compiler-Warnungen, die ich mit der aktuellsten ACE-Version beim Kompilieren kriege:
Quellcode:[ACE_ROOT]\ace_wrappers\ace\os_ns_stdio.h(120) : warning C4996: 'fileno': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _fileno. See online help for details.
c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(722) : see declaration of 'fileno'
Da weiß ich aber echt nicht, ob das zu ändern in meiner Macht liegt...

Editiert zum zweiten:
Auf manchen anderen PCs mit derselben VS und ACE Version schmeißt der Compiler den Error:
Quellcode:Error 6 error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall ACE_Time_Value::ACE_Time_Value(__int64,long)" (__imp_??0ACE_Time_Value@@QAE@_JJ@Z) referenced in function "public: static void __cdecl Message::recv(struct iovec *,class ACE_SOCK_Dgram *,class ACE_INET_Addr *)" (?recv@Message@@SAXPAUiovec@@PAVACE_SOCK_Dgram@@PAVACE_INET_Addr@@@Z) Message.obj TestACE Ich kann mir das nicht erklären. Die Include-Pfade und Libs und alles ist genauso da, wie auf meinem Entwicklungsrechner auch.

MfG,
Jean

--


Dieser Beitrag wurde am 29.07.2009 um 11:13 von LeJean bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche