Qt 动态加载动态库, QMetaObject元对象加载

由于通过pro文件加载第三方库导致程序崩溃(第三方库可能存在可能不存在,新旧版本在不同路径)

而通过自己构建空库在安装时会导致覆盖可能存在的第三方库

所以修改采用了QLibrary进行动态加载;

直接上代码#include "YHPostFaceLiving.h"

#include "../YHPostFaceLivingThird/YHPostFaceLivingThird.h"
#include <QCoreApplication>
#include <QDir>
#include "stable.h"
#include <QLibrary>
#include <QProcess>
extern "C" Q_DECL_EXPORT DeviceInterface *createDC(QString param)
{
    Q_UNUSED(param);
    return new YHPostFaceLiving();
}

class YHPostFaceLiving::PrivateData{
public:

};

YHPostFaceLiving::YHPostFaceLiving()
{
#ifdef Q_OS_WIN
    interFace = NULL;
#else
    interFace = loadDevice("param", "libYHPostFaceLivingThird.so");//动态加载
#endif

    QProcess *press = new QProcess;
    press->start("ls /lib64/libtesofacecv-living.so");//new sdk path
    press->waitForFinished();
    QByteArray output = press->readAllStandardOutput();
    QString x = output;
    if(interFace && (x != "")){
        faceliving = static_cast<YHPostFaceLiving *>(interFace);//DeviceInterface是基类
        //QObject *de = dynamic_cast<DeviceInterface*>(interFace);
        if (faceliving) {
            connect(faceliving, SIGNAL(error(int)), this, SLOT(get_error(int)));
            connect(faceliving, SIGNAL(remoteParam(QString)), this, SLOT(get_remoteParam(QString)));
            connect(faceliving, SIGNAL(imageCompResult(QString)), this, SLOT(get_imageCompResult(QString)));
            connect(faceliving, SIGNAL(programResult(QString,QString)), this, SLOT(get_programResult(QString,QString)));
            connect(faceliving, SIGNAL(programFail(QString,QString)), this, SLOT(get_programFail(QString,QString)));
            connect(faceliving, SIGNAL(getImageData(QString)), this, SLOT(get_getImageData(QString)));
            connect(faceliving, SIGNAL(openComplete()), this, SLOT(get_openComplete()));
            connect(faceliving, SIGNAL(closeComplete()), this, SLOT(get_closeComplete()));
            connect(faceliving, SIGNAL(resetComplete()), this, SLOT(get_resetComplete()));
            //下一次SDK更新确定版本号,通过版本号加载新旧SDK
            //QString version = getTesoVersion();
            //if(version != "3.2.1")
            //    faceliving = NULL;
            //LOGEVENT_INFO(QString("tesoface version :%1").arg(version));
        }
    } else {
        interFace = NULL;
        faceliving = NULL;
    }
}

YHPostFaceLiving::~YHPostFaceLiving()
{
    if (libLoader) {
        libLoader->unload();
        delete libLoader;
    }
    libLoader = NULL;

    if (interFace)
        delete interFace;
    interFace = NULL;

    if (faceliving)
        delete faceliving;
    faceliving = NULL;
}

DeviceInterface* YHPostFaceLiving::loadDevice(QString param, QString libname)
{
    typedef DeviceInterface* (*createDC)(QString);
    libLoader = new QLibrary();
    QString path = QCoreApplication::applicationDirPath() + QDir::separator() +
            QString("devices") + QDir::separator() + libname;
    libLoader->setFileName(path);
    LOGEVENT_INFO("path:" + path);
    if (!libLoader->load()) {
        LOGEVENT_INFO("err:" + libLoader->errorString());
        LOGEVENT_ERR(QString("third load lib false"));
        return NULL;
    }
    if (libLoader->isLoaded()) {
        createDC fun = (createDC)libLoader->resolve("createDC");
        if (fun) {
            return fun(param);
        } else {
            LOGEVENT_ERR(QString("createDC fun is NUll"));
            return NULL;
        }
    }

    return NULL;
}

QVariant YHPostFaceLiving::executeFunc(QString func, QMap<QString, QString> &funcParams)
{
    QVariant ret;
    bool bRes = false;
    const QMetaObject* mo = faceliving->metaObject();
    if (mo) {
        QMetaMethod m = mo->method(mo->indexOfMethod(func.toLocal8Bit().data()));
        QList<QByteArray> parameterNames = m.parameterNames();
        QList<QByteArray> parameterTypes = m.parameterTypes();

        QVariant val[10] = {QVariant()};
        for (int i = 0; i < parameterNames.size(); i++) {
            QString parame = parameterNames[i];
            if (funcParams.contains(parame)) {
                QString value = funcParams.value(parame);
                QString type = parameterTypes[i];
                //类型转换函数。其实可以只用另外一个executeFunc 参数通过QVariant(param)进行转换进去
                val[i] = DeviceInterface::getParamVale(value, type.toLocal8Bit().data());
            } else {
                LOGEVENT_ERR(QString("can't not find the parameter name[%1] in fun[%2], maybe you change the function").arg(parame).arg(func));
            }
        }
        bRes = executeFunc(func, ret, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9]);
    }

    return ret;
}

bool YHPostFaceLiving::executeFunc(QString func, QVariant &ret, QVariant val0, QVariant val1, QVariant val2, QVariant val3, QVariant val4, QVariant val5, QVariant val6, QVariant val7, QVariant val8, QVariant val9)
{
    bool bRes = false;
    const QMetaObject* mo = faceliving->metaObject();
    int nIndex = mo->indexOfMethod(func.toLocal8Bit().data());
    if (-1 != nIndex) {
        QMetaMethod m = mo->method(nIndex);
        QList<QByteArray> parameterTypes = m.parameterTypes();
        QGenericArgument val[10] = { QGenericArgument() };

        QVariant valIn[] = { val0, val1, val2, val3, val4, val5, val6, val7, val8, val9 };
        for (int i = 0; i < parameterTypes.size(); i++) {
            if (!valIn[i].convert(QMetaType::type(parameterTypes[i].data()))) {
                LOGEVENT_ERR(QString("executeFunc convert param[%1] error!").arg(i));
            }
            val[i] = QGenericArgument(parameterTypes[i].data(), &valIn[i].data_ptr().data);
        }

        //创建保存返回值的变量。
        QGenericReturnArgument retArgument = QGenericReturnArgument();
        Qt::ConnectionType connectType = Qt::AutoConnection;
        if (QString("void").compare(m.typeName())) {
            connectType = Qt::DirectConnection;
            ret = DeviceInterface::getParamVale("", m.typeName());
            retArgument = QGenericReturnArgument(m.typeName(), &ret.data_ptr().data);
            LOGEVENT_DEBUG(QString("executeFunc call function[%1] direct.").arg(func));
        }
        bRes = m.invoke(faceliving, connectType, retArgument,
                        val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7],
                val[8], val[9]);
        if (!bRes)
            LOGEVENT_ERR(QString("executeFunc call func[%1] error, object[%2]").arg(func).arg(faceliving->metaObject()->className()));
    } else {
        LOGEVENT_ERR(QString("executeFunc call func[%1] error, can't find func, object[%2]").arg(func).arg(faceliving->metaObject()->className()));
        Q_ASSERT(false);
    }
    return bRes;

}

void YHPostFaceLiving::connectEvent(QObject *dc, const QObject *receiver, const char *member)
{
    connect(dc, SIGNAL(deviceevent(QObject*,QString,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant,QVariant)),
            receiver, member, Qt::QueuedConnection);
}

void YHPostFaceLiving::get_remoteParam(QString result)
{
    emit_deviceevent("remoteParam(QString)", result);
}

void YHPostFaceLiving::get_imageCompResult(QString result)
{
    emit_deviceevent("imageCompResult(QString)", result);
}

void YHPostFaceLiving::get_programResult(QString serName, QString result)
{
    emit_deviceevent("programResult(QString,QString)", serName, result);
}

void YHPostFaceLiving::get_programFail(QString serName, QString result)
{
    emit_deviceevent("programFail(QString,QString)", serName, result);
}

void YHPostFaceLiving::get_getImageData(QString imageData)
{
    emit_deviceevent("getImageData(QString)", imageData);
}

void YHPostFaceLiving::get_openComplete()
{
    emit_deviceevent("openComplete()");
}

void YHPostFaceLiving::get_closeComplete()
{
    emit_deviceevent("closeComplete()");
}

void YHPostFaceLiving::get_resetComplete()
{
    emit_deviceevent("resetComplete()");
}

void YHPostFaceLiving::get_error(int error)
{
    emit_deviceevent("error(int)", error);
}
/*
int YHPostFaceLiving::analyFmlFile()
{
    if(faceliving){
        QMap<QString,QString> funcParams;
        int ret = executeFunc("analyFmlFile()", funcParams).toInt();
        return ret;
    }
    return 1;
}

void YHPostFaceLiving::loadenv(const QString &envPath)
{
    if(faceliving){
        QMap<QString,QString> funcParams;
        funcParams.insert("envPath", envPath);
        executeFunc("loadenv(QString)",funcParams);
    }
}
*/

void YHPostFaceLiving::open()
{
    if (faceliving) {
        QMap<QString, QString> funcParams;
        executeFunc("open()", funcParams);
    } else {
        emit_deviceevent("hardware_Error()");
    }
}

bool YHPostFaceLiving::openSync()
{
    if (faceliving) {
        QMap<QString, QString> funcParams;
        bool ret = executeFunc("openSync()", funcParams).toBool();
        return ret;
    } else {
        return DeviceInterface::openSync();
    }
}

void YHPostFaceLiving::close()
{
    if (faceliving) {
        QMap<QString, QString> funcParams;
        executeFunc("close()", funcParams);
    } else {
        DeviceInterface::close();
    }
}

bool YHPostFaceLiving::closeSync()
{
    if (faceliving) {
        QMap<QString, QString> funcParams;
        bool ret = executeFunc("closeSync()", funcParams).toBool();
        return ret;
    } else {
         return DeviceInterface::closeSync();
    }
}

void YHPostFaceLiving::Reset(QString)
{
    DeviceInterface::Reset();
}

long YHPostFaceLiving::winId()
{
    if (faceliving == NULL)
        return -1;

    QMap<QString,QString> funcParams;
    long ret = (long)executeFunc("winId()", funcParams).toInt();
    return ret;
}

void YHPostFaceLiving::setParent(uint winid)
{
    if (faceliving == NULL)
        return;

    QMap<QString,QString> funcParams;
    funcParams.insert("winid", QString("%1").arg(winid));
    executeFunc("setParent(uint)", funcParams);
}

void YHPostFaceLiving::setGeometry(int x, int y, int width, int height)
{
    if (faceliving == NULL)
        return;

    QMap<QString,QString> funcParams;
    funcParams.insert("x", QString("%1").arg(x));
    funcParams.insert("y", QString("%1").arg(y));
    funcParams.insert("width", QString("%1").arg(width));
    funcParams.insert("height", QString("%1").arg(height));
    executeFunc("setGeometry(int,int,int,int)", funcParams);
}

void YHPostFaceLiving::showDisplay(bool show)
{
    if (faceliving == NULL)
        return;

    QMap<QString, QString> funcParams;
    funcParams.insert("show", QString("%1").arg(show));
    executeFunc("showDisplay(bool)", funcParams);
}

QString YHPostFaceLiving::getTesoVersion()
{
    if (faceliving == NULL)
        return QString();

    QMap<QString, QString> funcParams;
    QString ret = executeFunc("getTesoVersion()", funcParams).toString();
    return ret;
}

void YHPostFaceLiving::setTesoParam(const QString &params)
{
    if (faceliving == NULL)
        return;

    QMap<QString, QString> funcParams;
    funcParams.insert("params", params);
    executeFunc("setTesoParam(QString)", funcParams);
}

QString YHPostFaceLiving::getTesoParam()
{
    if (faceliving == NULL)
        return QString();

    QMap<QString,QString> funcParams;
    QString ret = executeFunc("getTesoParam()", funcParams).toString();
    return ret;
}

void YHPostFaceLiving::setEndPoint(const QString &url)
{
    Q_UNUSED(url);
}

void YHPostFaceLiving::getRemoteParam(const QString &info)
{
    Q_UNUSED(info);
}

void YHPostFaceLiving::faceCompare(const QString &params)
{
    Q_UNUSED(params);
}

QString YHPostFaceLiving::getDevicePublicKey()
{
    if (faceliving == NULL)
        return QString();

    QMap<QString,QString> funcParams;
    QString ret = executeFunc("getDevicePublicKey()", funcParams).toString();
    return ret;
}

bool YHPostFaceLiving::importDefaultCDK(QString cdk)
{
    if (faceliving == NULL)
        return false;

    QMap<QString,QString> funcParams;
    funcParams.insert("cdk", cdk);
    bool ret = executeFunc("importDefaultCDK(QString)", funcParams).toBool();
    return ret;
}

QString YHPostFaceLiving::getCDKCheckValue()
{
    if (faceliving == NULL)
        return QString();

    QMap<QString,QString> funcParams;
    QString ret = executeFunc("getCDKCheckValue()", funcParams).toString();
    return ret;
}

bool YHPostFaceLiving::importWorkKey(QString key)
{
    if (faceliving == NULL)
        return false;

    QMap<QString, QString> funcParams;
    funcParams.insert("key", key);
    bool ret = executeFunc("importWorkKey(QString)", funcParams).toBool();
    return ret;
}

QString YHPostFaceLiving::getCameraStatus()
{
    if (faceliving == NULL)
        return QString();

    QMap<QString, QString> funcParams;
    QString ret = executeFunc("getCameraStatus()", funcParams).toString();
    return ret;
}


bool YHPostFaceLiving::echoFaceImage(bool showOrCollect)
{
#ifdef Q_OS_WIN
    return false;
#else
    if (faceliving == NULL)
        return false;

    QMap<QString,QString> funcParams;
    funcParams.insert("showOrCollect",QString("%1").arg(showOrCollect));
    bool ret = executeFunc("echoFaceImage(bool)", funcParams).toBool();
    return ret;
#endif
}


void YHPostFaceLiving::startCamera()
{
    if (faceliving == NULL)
        return;

    QMap<QString,QString> funcParams;
    executeFunc("startCamera()", funcParams);
}

void YHPostFaceLiving::stopCamera()
{
    if (faceliving == NULL)
        return;

    QMap<QString,QString> funcParams;
    executeFunc("stopCamera()", funcParams);
}

void YHPostFaceLiving::capture()
{
    if (faceliving == NULL)
        return;

    QMap<QString,QString> funcParams;
    executeFunc("capture()", funcParams);
}

QString YHPostFaceLiving::errorStr(int errNo)
{
    if (faceliving == NULL)
        return QString();

    QMap<QString, QString> funcParams;
    funcParams.insert("errNo", QString("%1").arg(errNo));
    QString ret = executeFunc("errorStr(bool)", funcParams).toString();
    return ret;
}

bool YHPostFaceLiving::setTuxedoParan(const QString &tag, const QString &value)
{
    if (faceliving == NULL)
        return false;

    QMap<QString,QString> funcParams;
    funcParams.insert("tag",tag);
    funcParams.insert("value",value);
    bool ret = executeFunc("setTuxedoParan(QString,QString)", funcParams).toBool();
    return ret;
}

QString YHPostFaceLiving::getTuxedoParan(const QString &tag)
{
    if (faceliving == NULL)
        return QString();

    QMap<QString, QString> funcParams;
    funcParams.insert("tag", tag);
    QString ret = executeFunc("getTuxedoParan(QString)", funcParams).toString();
    return ret;
}

void YHPostFaceLiving::loadEnv(const QString &envPath)
{
    if (faceliving == NULL)
        return;

    QMap<QString, QString> funcParams;
    funcParams.insert("envPath", envPath);
    executeFunc("loadEnv(QString)", funcParams);
}

int YHPostFaceLiving::tuxedoCommuncation(const QString &service, const QString &buff, const QString &reStr, int rcvlenth)
{
    if (faceliving == NULL)
        return 0;

    QMap<QString, QString> funcParams;
    funcParams.insert("service", service);
    funcParams.insert("buff", buff);
    funcParams.insert("reStr", reStr);
    funcParams.insert("rcvlenth", QString("%1").arg(rcvlenth));
    int ret = executeFunc("tuxedoCommuncation(QString,QString,QString,int)", funcParams).toInt();
    return ret;
}

bool YHPostFaceLiving::analysFmlFile(const QString &fmlpath)
{
    if (faceliving == NULL)
        return false;

    QMap<QString, QString> funcParams;
    funcParams.insert("fmlpath",fmlpath);
    bool ret = executeFunc("analysFmlFile(QString)", funcParams).toBool();
    return ret;
}

QByteArray YHPostFaceLiving::formatBuff(const QString &buff)
{
    if (faceliving == NULL)
        return QByteArray();

    QMap<QString, QString> funcParams;
    funcParams.insert("buff", buff);
    QByteArray ret = executeFunc("formatBuff(QString)", funcParams).toByteArray();
    return ret;
}

int YHPostFaceLiving::sendBuff(const QString &serName, const QByteArray &buff, const QString &reStr)
{
    if (faceliving == NULL)
        return 0;

    QMap<QString, QString> funcParams;
    funcParams.insert("serName", serName);
    funcParams.insert("buff", buff);
    funcParams.insert("reStr", reStr);
    int ret = executeFunc("sendBuff(QString,QByteArray,QString)", funcParams).toInt();
  //int ret = executeFucn("sendBuff(QString,QByteArray,QString)", QVariant(serName), QVariant(buff), QVariant(reStr));
return ret; }

 

本次代码修改之后,对元对象的功能作用,接口有了一定理解。

对动态库加载有了实践。

:-D

转载于:https://www.cnblogs.com/warmSnowFY/p/11325857.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值