c++ - 调用动态加载的库的非静态类成员函数

标签 c++ qt dynamic shared-libraries

我正在使用KWallet编写具有可选运行时依赖项的应用程序。这意味着如果在用户系统上安装了KWallet,它将被使用,如果不是,它仍然可以工作,但是没有KWallet支持。

这是我加载库的方式,它是包装类的静态属性。然后在状态下的构造函数中,我从库中解析符号。

QLibrary Core::PSE::KWallet::lib("KF5Wallet");
...
lib.load();  
openWallet = (OpenWallet) lib.resolve("_ZN7KWallet6Wallet10openWalletERK7QStringyNS0_8OpenTypeE");
networkWallet = (NetworkWallet) lib.resolve("_ZN7KWallet6Wallet13NetworkWalletEv");
destructor = (Destructor) lib.resolve("_ZN7KWallet6WalletD2Ev");


与QLibrary相同-函数也是类的静态成员,但我不确定这是否是一个好主意。
这是我类的定义
typedef ::KWallet::Wallet* (*OpenWallet)(const QString &, WId, ::KWallet::Wallet::OpenType);
typedef QString (*NetworkWallet)();
typedef void (*WalletOpened)(bool);
typedef void (*Destructor)();

static OpenWallet openWallet;
static NetworkWallet networkWallet;
static Destructor destructor;

这是我分配对象的方式
wallet = openWallet(networkWallet(), 0, ::KWallet::Wallet::Asynchronous);

一切正常,直到需要执行非静态成员,尤其是析构函数为止。据我所知,应该看起来像那样
((*wallet).(destructor))()

但这似乎不起作用。我是这个主题的新手,即使我以正确的方式开始,我也不知道。

那么,如何调用这种方式加载的类的析构函数呢?如何调用其他成员?还是我最好以完全其他的方式来做?

附言我知道,有一个用于KWallet的DBUS API,甚至还有一些包装器库,例如qtkeychain,但我想了解使用此示例进行这种依赖的方式。

最佳答案

我找到了解决方案。

这个想法是用包装函数编写一个小的共享库

extern "C" KWallet::Wallet* openWallet(const QString &name, WId w, KWallet::Wallet::OpenType ot = KWallet::Wallet::Synchronous) {
    return KWallet::Wallet::openWallet(name, w, ot);
}
extern "C" void deleteWallet(KWallet::Wallet* w) {
    w->deleteLater();
}
extern "C" const char* networkWallet() {
    return KWallet::Wallet::NetworkWallet().toStdString().c_str();
}
extern "C" int readPassword(KWallet::Wallet* w, const QString &key, QString &value) {
    return w->readPassword(key, value);
}

我们将此小包装器称为foo.so。因此,然后在构建时构建此foo.so并目标链接到实际依赖项(在我的情况下为KWallet)。

然后在主代码中,您将尝试动态加载此foo.so,而不是KWallet本身。如果启动计算机上不存在KWallet,则该foo.so根本不会加载,而是我必须知道的窍门!

然后,您当然可以像这样解析符号
QLibrary Core::PSE::KWallet::lib("foo");
...
lib.load();  
openWallet = (OpenWallet) lib.resolve("openWallet");
networkWallet = (NetworkWallet) lib.resolve("networkWallet");
deleteWallet = (DeleteWallet) lib.resolve("deleteWallet");
readPassword = (ReadPassword) lib.resolve("readPassword");

然后这样称呼它
wallet = openWallet(networkWallet(), 0, ::KWallet::Wallet::Asynchronous);
...
QString password;
int result = readPassword(wallet, *i, password);
...
deleteWallet(wallet);

关于c++ - 调用动态加载的库的非静态类成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61120185/

相关文章:

c++ - SWIG C++ Python 多态和多线程

c++ - 如何在 Qt 中为文本编辑程序实现 "Do you want to save changes?"对话框?

c++ - C++ 中的动态数组大小

c# - 无法使用 Rob Conery 的 Massive 保存列表<dynamic>

c# - 当我尝试使用 DynamicMethod 创建始终返回 true 的方法时出现错误

c++ - 无法使用 libxml2 和 xpath 获取节点

c++ - 取消引用从函数返回的shared_ptr

c++键盘记录器无法正常工作

qt - Qt 中的样式表、隐藏的小部件和大小

c++ - 如何在 Qt 上运行 AudioOutput 示例代码?