Неправильная загрузка динамической библиотеки при использовании абсолютного FilePath - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть следующий код, который записывает два раза в файл cpp, а затем компилирует файл cpp и выполняет получившиеся общие библиотеки: (на macOS)

#include <QCoreApplication>
#include <QString>
#include <QDebug>
#include <QLibrary>
#include <QProcess>
#include <QFileInfo>

void compileAndExecute(QFileInfo source, QString libName){
    QString libPath = source.absolutePath()+"/"+libName + ".so";
    QString rename = "test.so";
    QProcess p;
    //QString cmd = "g++ -shared -fPIC -std=c++14 -O3 " + source.absoluteFilePath() + " -o " + QFileInfo(rename).absoluteFilePath() + " ";
    QString cmd = "g++ -shared -fPIC -std=c++14 -O3 " + source.absoluteFilePath() + " -o " + rename + " ";
    qDebug() << cmd;
    p.start("bash", QStringList() << "-c" << cmd);
    p.waitForFinished();
    qDebug().noquote() <<"ERR : "<< QString(p.readAllStandardError());
    qDebug().noquote() <<"OuT : "<< QString(p.readAllStandardError());
    if(p.exitCode() != 0){
        qDebug() << p.errorString();
        qDebug() << p.error();
    }else{
        if(p.exitCode()==0){
            QFile::rename(rename,libPath );
            QLibrary lib(libPath);
            if(lib.load()){
                auto f = lib.resolve("print");
                if(f)
                    f();
                else
                    qDebug() << "Error, Function is null";
            }else{
                qDebug() << "Error loading lib";
            }
        }
    }
}

QFileInfo generateCode(int numberPrinted, QString filename){
    QFile file( filename );
    Q_ASSERT( file.open(QIODevice::ReadWrite) );

    QTextStream stream( &file );
    stream << "#include <iostream>" << endl;
    stream << "extern \"C\" { " << endl;
    stream << " void print(){" << endl
           << "     std::cout << " + QString::number(numberPrinted) + " << std::endl;" << endl
           << " }" << endl;
    stream << "}" << endl;
    stream.flush();
    file.close();
    return file;
}

int main(int argc, char *argv[])
{

    compileAndExecute(generateCode(1,"Source.cpp"),"lib1");
    compileAndExecute(generateCode(2,"Source.cpp"),"lib2");
    QFile::remove("Source.cpp");
    QFile::remove("lib1.so");
    QFile::remove("lib2.so");
    return 0;
}

когда я его выполняю, я получаюправильный результат:

1
2

Но когда я изменяю строку 4 в функции compileAndExecute с " -o " + rename на " -o " + QFileInfo(rename).absoluteFilePath(), я получаю вывод

1
1

Вторая библиотека не будет загружаться правильно,Функция разрешения вернет точно такой же адрес для указателя функции.

Может кто-нибудь объяснить это поведение?

...