2016-03-20 7 views
0

Ich versuche, ein gemeinsames Objekt (SensorTemp abgeleitete Klasse) zur Laufzeit mit dem API dlopen() zu laden. Wenn ich versuche, zu statisch-Fall den Zeiger auf den entsprechenden Funktionszeiger, erhalte ichC++ statische Umwandlung mit .so Laden zur Laufzeit

LinkTest.cpp:26:48: error: invalid static_cast from type ‘void*’ to type ‘Sensor*()’ 
Sensor* mySensor = static_cast<Sensor *()>(mkr)(myHub, a, b, c, d, e); 

Hier ist der relevante Sensor.h Basisklassenkonstruktor:

class Sensor 
{ 
public: 
    Sensor(Hub& _pHub, const std::string& _name, const std::string& _type, const std::string& _logLevel, const std::string& _configInfo, const std::string& _location): m_pHub(&_pHub), m_name(_name), m_type(_type), m_logLevel(_logLevel), m_configInfo(_configInfo), m_location(_location) {} 

abgeleiteten Klasse SensorTemp.h: (sein CTOR ruft die Basis CTOR)

#include "Sensor.h" 

class SensorTemp : public Sensor 
{ 
public: 
    SensorTemp(Hub& _pHub, const std::string& _name, 
          const std::string& _type, 
          const std::string& _logLevel, 
          const std::string& _configInfo, 
          const std::string& _location); 
    ~SensorTemp() {} 
    void* Run(); 
private: 
    int m_lowTemp; 
    int m_highTemp; 
    int m_interval; 
}; 

extern "C" 
{ 
    SensorTemp* Create(Hub& _pHub, const std::string& _name, 
            const std::string& _type, 
            const std::string& _logLevel, 
            const std::string& _configInfo, 
            const std::string& _location) 
    { 
     return new SensorTemp(_pHub, _name, _type, _logLevel, _configInfo, _location); 
    } 

} 

#endif //__SENSORTEMP_H__ 

der Test:

int main(int argc, char **argv) 
{ 
    Hub myHub; 
    string a = "A"; 
    string b = "B"; 
    string c = "C"; 
    string d = "D"; 
    string e = "E"; 
    string f = "F"; 
    void *hndl = dlopen("./libSensorTemp.so", RTLD_LAZY); 
    if(hndl == NULL) 
    { 
     std::cerr << dlerror() << std::endl; 
     exit(-1); 
    } 
    void *mkr = (Sensor*)dlsym(hndl, "Create"); 
    Sensor* mySensor = static_cast<Sensor *()>(mkr)(myHub, a, b, c, d, e); 
    mySensor->Run(); 

} 
+1

Werfen Sie einen Blick auf [diese Frage] (http://stackoverflow.com/questions/1096341/function-pointers-ca Stech-in-c). –

Antwort

1

In Bezug auf this question, hier ist ein vereinfachtes Beispiel:

#include <dlfcn.h> 
#include <string> 

class Sensor; 
class Hub; 

extern "C" 
{ 
    Sensor* Create(Hub& _pHub 
     , const std::string& _name 
     , const std::string& _type 
     , const std::string& _logLevel 
     , const std::string& _configInfo 
     , const std::string& _location) 
    { 
     return nullptr; 
    } 
} 



int main(int argc, char **argv) 
{ 
    void *hndl = dlopen("./libSensorTemp.so", RTLD_LAZY); 
    if(hndl == NULL) { 
     exit(-1); 
    } 

    void *mkr = (Sensor*)dlsym(hndl, "Create"); 

    typedef Sensor*(*create_fn)(Hub& 
     , const std::string& 
     , const std::string& 
     , const std::string& 
     , const std::string& 
     , const std::string&); 

    create_fn creator = 0; 
    *reinterpret_cast<void**>(&creator) = mkr; 

    // .... 
} 
+0

Danke! Ich lese die Referenz, kann aber die Logik hinter den letzten beiden Zeilen nicht verstehen: warum die = 0? und warum neu interpretieren als nichtig **? ist nicht der Zweck, einen void-Zeiger in einen Funktionszeiger umzuwandeln? – susdu

+1

Die '= 0' ist so, dass wir die Funktionszeigervariable auf einen vernünftigen Wert initialisiert haben. Der Grund für das 'void **' ist, dass Sie den Funktionszeiger nicht direkt in den Objektzeiger konvertieren können. Ein Zeiger auf einen Funktionszeiger (d. H. "Create_fn *") ** ist jedoch ein Objektzeiger. So ist 'void **'. Daher können wir zwischen den beiden konvertieren. Mit '* reinterpret_cast (& creator)' interpretieren wir den Ersteller neu als 'void *' und die Zuweisung ist gültig. –

+0

Das Problem ist jetzt './libSensorTemp.so: undefiniertes Symbol: _ZTI6Sensor'. Wenn die abgeleitete Klasse CTOR die Basis-Klasse aufruft, wird der Name des Basis-CTORs nicht erkannt und kann nicht aufgelöst werden. – susdu

1

Ihre Umwandlung in einen Zeiger auf die Funktion ist falsch. Der Code sollte sein:

void *mkr = (void *)dlsym(hndl, "Create"); // only the address matters here 
Sensor* mySensor = static_cast<Sensor *(*)(Hub&, const std::string&, const std::string&, 
    const std::string&, const std::string&, const std::string&)>(mkr)(myHub, a, b, c, d, e); 
mySensor->Run(); 

Weil Sie wollen mkr-einen Zeiger auf eine Funktion werfen unter einer Hub Referenz und 5 string Referenzen und Rückgabe eines Zeigers auf Sensor

+0

'LinkTest.cpp: 27: 69: Fehler: Ungültige statische_Sendung vom Typ 'void *' zur Eingabe von 'Sensor * (*) (Hub &, Konstante Zeichenfolge &, Konstante Zeichenfolge &, Konstante Zeichenfolge &, Konstante Zeichenfolge &, Konstante Zeichenfolge &) {aka Sensor * (*) (Hub &, const std :: basic_string &, const std :: basic_string &, const std :: basic_string &, const std :: basic_string &, const std :: basic_string &)}‘ const std :: string &, const std :: Zeichenkette &, const std :: Zeichenkette &)> (mkr) (myHub, a, b, c, d, e); ' – susdu

+0

Welchen Compiler benutzen Sie? Ich kann den Fehler nicht reproduzieren. Ich testete meinen Code mit MSVC2008 Express ... –

+0

Ich benutze gcc, aber wenn es Compiler ist, ist es wahrscheinlich nicht die beste Lösung – susdu

Verwandte Themen