Добрый день! Настал час, когда пришлось писать динамические библиотеки.
В проге через QLibrary подключается библиотека и далее используются ее функции.
В коде самой dll содержится класс, методы которого нужно вызывать, но в отличии от статической библиотеки, в динамической методы вызывать нельзя, только функции, Я поступил следующим образом:
class MyLib
{
public:
MyLib();
QString Test() {return "Hello!";};
};
MyLib lblb; // создаем класс
extern "C" {
QString Test() {return lblb.Test();}
}
А http://qt-project.org/doc/qt-5/QtPlugin.html разве не удобнее использовать?
И еще, хочу в программе отображать виджет, созданный в библиотеке (библиотека должна им управлять, реагировать на сигналы и т.д.), программа только отображать. Сделал так:
*.h библиотеки:
extern "C" {
QString Test();
QWidget *widget();
}
class MyLib : public QObject
{
Q_OBJECT
public:
MyLib();
struct {
QLabel *label;
QPushButton *button;
} w;
QWidget *widget;
private slots:
void tim();
};
MyLib lb; // создаем класс
QString Test(){return lb.Test();}
QWidget *widget() {return lb.widget;}
MyLib::MyLib()
{
qDebug() << "MyLib";
widget = new QWidget();
widget->setLayout(new QVBoxLayout);
widget->layout()->addWidget(w.label = new QLabel());
widget->layout()->addWidget(w.button = new QPushButton("Update"));
connect(w.button, SIGNAL(clicked()), this, SLOT(tim()));
}
void MyLib::tim()
{
w.label->setText(QDateTime::currentDateTime().toString());
}
QLibrary *lib = new QLibrary("d:/MyLib1.dll", this);
qDebug() << lib->load();
typedef QWidget* (*Fct) ();
Fct fct = (Fct)(lib->resolve("widget"));
QWidget *w = fct();
ui->tabWidget->addTab(w, "dgdg");
arial, Есть вероятность, что dll будут собираться иными компиляторами (использование виджетов будет не обязательным), поэтому я и предположил, что их выгодней использовать))))
class MyLib : public QObject
MishaUA, не вижу у тебя инициализации структуры w
А вообще сделай функцию, которая будет создавать экземпляр (объект), а дальше работай с ним как обычно.
class MyWidget : public QWidget
{
public:
MyWidget (arg1, arg2, ...);
}
MyWidget* creatMyWidget(arg1, arg2, ...)
{
return new MyWidget(arg1, arg2, ...)
}
QLibrary *lib = new QLibrary("d:/MyLib1.dll", this);
qDebug() << lib->load();
typedef QWidget* (*CreatMyWidget) ();
CreatMyWidget creatMyWidget = (CreatMyWidget)(lib->resolve("widget"));
QWidget *w = creatMyWidget();
...
да, выше Юрий правильно заметил, что работа с классами есть самое обычное дело. экспортируется весь класс и проблем нет. более того, можно даже наследоваться от классов, объявленных в других библиотеках. я тут где-то про такой случай писала.
единственная возможная проблема - это не будет работать с разными компиляторами. то есть, если основная программа скомпилена одним компилятором, а библиотеки - другим. а у мелкософта иногда даже разные версии компиляторов не совместимы. так что тут надо понимать, как это потом будет эксплуатироваться. если предполагается, что другие программисты будут собирать какие-то внешние модули, то получится ограничение на выбор компилятора.
и ещё видимость классов у GCC и MSVC разная. но обычно это не представляет проблемы.
Спасибо за ответы!
Еще интересует, при загрузке библиотеки она будет работать в том же потоке программы, в котором она была загружена?
во всех потоках. у потоков общая память. то есть, как обычный класс, определённый в программе.
если в библиотеке есть статические переменные - они будут статическими и общими для всех потоков.
Тут правильнее речь вести об объекте (экземпляре класса). В каком потоке ты его создаёшь, в том он и будет жить.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)