У меня есть следующий код, который записывает два раза в файл 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
Вторая библиотека не будет загружаться правильно,Функция разрешения вернет точно такой же адрес для указателя функции.
Может кто-нибудь объяснить это поведение?