首先對不起我的英文如何使用QPluginLoader在Qt中創建同一個插件的多個實例?
我開發了使用Qt的財務打印機驅動程序。驅動程序細節是通過RS232在PC和設備之間進行通信。存儲在共享對象(Qt插件)中的驅動程序和服務器通過QPluginLoader執行加載。
因此,關於我的問題...當我使用一個設備和一個驅動程序實例都工作正常,但是當我附加很多設備(例如3)時,只有最後加載的設備工作。我已經完成了許多代碼檢查,讀取了許多日誌數據轉儲,設備和端口命名沒有錯誤,但是如果我使用命令來處理第一個設備 - 兩個左側設備接收到相同的命令(根據日誌條目)並且只有最後一個加載設備執行命令執行。
例如:從我的服務器我發送PrintReceipt命令到設備1,在設備1的日誌文件我看到條目:PrintReceipt,在設備2的日誌文件我看到條目:PrintReceipt,:PrintReceipt,和日誌文件設備3我看到3個相同的條目。所以,當我看到我的問題 - QPluginLoader爲第一個加載的設備創建驅動程序的一個實例,然後,當我嘗試加載驅動程序到第二個設備時 - QPluginLoader創建新的實例並替換最近創建的第一個設備的驅動程序等等每個設備。所以,至少,我只有一個驅動程序(插件)的實例,許多設備和我的應用程序邏輯崩潰。
我的問題是:如何使用QPluginLoader在Qt中創建同一個插件的多個實例?我的驅動程序界面和下面列出的加載代碼。
class IPrinterDriver : public QObject
{
public:
// Printer driver initialization
virtual bool Init(QextSerialPort* port, const QString& deviceID) = 0;
// Driver identify name
virtual QString GetName() = 0;
// Gets current device state
virtual DeviceStates GetState() = 0;
// Gets device info and state test
virtual QString DeviceInfo() = 0;
// Set print mode to specified
virtual bool SetPrintMode(PrintModes mode) = 0;
// Get current print mode
virtual PrintModes PrintMode() const = 0;
// Sets device password from configuration
virtual void SetDevicePasswords(int operatorPassword, int adminPassword) = 0;
// Sets non-fiscal permissoin to device
virtual void SetNonFiscalModePermission(bool allowed) = 0;
// Gets device operator password
virtual int GetOperatorPassword() const = 0;
// Gets device administrator password
virtual int GetAdministratorPassword() const = 0;
// Gets non-fiscal mode permission
virtual bool GetNonFiscalModePermission() const = 0;
// Payment transaction
virtual bool PaymentTransaction(PaymentItem& item) = 0;
// Query device for X-Report
virtual bool GetXReport() = 0;
// Encashment transaction (Z-Report)
virtual bool Encash(bool fromBuffer) = 0;
// Print transaction
virtual bool Print(QString& text) = 0;
// Performs fiscal sale at device and returns receipt data
virtual FiscalReceiptData FPSSale(int requestID, int amount) = 0;
// Gets last fiscal receipt data
virtual FiscalReceiptData GetLastReceiptData() = 0;
// Gets serial port assigned to device
virtual QextSerialPort* GetDevicePort() = 0;
signals:
// Emits when device logging needed
virtual void DeviceLoggingNeeded(LogEntry entry, const QString& deviceID) = 0;
};
Q_DECLARE_INTERFACE(IPrinterDriver, "InfSys.Devices.IPrinterDriver/1.0")
和驅動程序加載方法:
// Performs loading specified driver for device at specified port
IPrinterDriver* PrintSystem::LoadDriver(PortConfiguration portConfig, const QString& driverName, const QString& adminPassword, const QString& operPassword, const QString& deviceID)
{
IPrinterDriver* result = NULL;
// Prepare plugin loader
QDir driversDir(_driversPath);
QStringList filesMask;
filesMask << tr("libdriver.%1.*").arg(driverName);
driversDir.setNameFilters(filesMask);
QStringList driversFiles = driversDir.entryList(QDir::Files);
// Load plugin with specified driver
foreach(QString driverFile, driversFiles)
{
// Load current driver;
QString driverFileName = driversDir.absoluteFilePath(driverFile);
QPluginLoader driversLoader(driverFileName);
// Try to init driver
QObject *driverObject = driversLoader.instance();
if (driverObject)
{
result = qobject_cast<IPrinterDriver *>(driverObject);
if (result && (result->GetName() == driverName))
{
QextSerialPort* devicePort = ConfigureSerialPort(portConfig);
if (devicePort == NULL)
{
driversLoader.unload();
return NULL;
}
// Init device
result->SetDevicePasswords(operPassword.toInt(), adminPassword.toInt());
result->SetNonFiscalModePermission(false);
result->SetPrintMode(Fiscal);
connect(result, SIGNAL(DeviceLoggingNeeded(LogEntry,QString)), App->LoggingModule, SLOT(OnDeviceLoggingNeeded(LogEntry,QString)), Qt::QueuedConnection);
bool initResult = result->Init(devicePort, deviceID);
if (!initResult)
{
driversLoader.unload();
return NULL;
}
}
else
driversLoader.unload();
}
}
return result;
}