我尝试使用dlopen()API在运行时加载共享对象(SensorTemp
派生类)。当我尝试将指针指向适当的函数指针时,我得到
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);
这里是相关的Sensor.h
基类构造函数:
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) {}
派生类SensorTemp.h
:(其CTOR称之为基础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__
测试:
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();
}
答案 0 :(得分:1)
你对指向函数的指针是错误的。你的代码应该是:
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();
因为您希望将mkr
转换为一个指向函数的指针,该函数接受一个Hub
引用和5个string
引用并返回指向Sensor
的指针
答案 1 :(得分:1)
参考this question,这是一个简化的例子:
#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;
// ....
}