0

我正在尝试使用 QAxObject 打开一个 Excel 文件并读取其数据。我已经在主线程中成功完成了这项工作,但是现在,我想在 2 个单独的线程中执行“打开”和“读取”操作。为此,我创建了 2 个继承自 QThread 的类。'OpenerThread' 打开文件没有任何问题。一旦这个线程结束,'ReadManagerThread' 开始工作。
但是,应用程序在“QAxObject * rows = range->querySubObject( "Rows" );" 行中崩溃
我收到错误“QAxBase::dynamicCallHelper:对象不支持自动化”。
此错误的原因是什么,我该如何解决?

ExcelManager.h

 // Note: The pointers used to open and read the Excel file are global and wrapped in this namespace.
 // Therefore, they're supposed to be accessible by different threads.

namespace ExcelManager {

extern QAxObject* excel;
extern QAxObject* workbooks;
extern QAxObject* workbook;
extern QAxObject* sheets;
extern QAxObject* sheet;
extern int fileRowCount;

void openExcelFile();
void setFileRowCount();
}

ExcelManager.cpp

QAxObject* ExcelManager::excel;
QAxObject* ExcelManager::workbooks;
QAxObject* ExcelManager::workbook;
QAxObject* ExcelManager::sheets;
QAxObject* ExcelManager::sheet;


void ExcelManager::openExcelFile(){

    ExcelManager::excel     = new QAxObject("Excel.Application");
    ExcelManager::workbooks = excel->querySubObject("Workbooks");       
    ExcelManager::workbook  = workbooks->querySubObject("Open(const QString&)" ,"AppAddress\\Book2.xlsx");       
    ExcelManager::sheets    = workbook->querySubObject("Worksheets");
    ExcelManager::sheet     = sheets->querySubObject("Item(int)", 1);        
}


void ExcelManager::setFileRowCount(){

    QAxObject * range = ExcelManager::sheet->querySubObject("UsedRange"); 

    QAxObject * rows = range->querySubObject( "Rows" );
    // After ReadManagerThread calls this function, 
    // this is the line on which the app crashes. Based on debugging results,
    // 'range' does not point to anything at this moment, but why?

    ExcelManager::fileRowCount = rows->dynamicCall( "Count()" ).toInt();
}

OpenerThread.h

#include <QThread>
#include <Ole2.h>
#include "ExcelManager.h"

class OpenerThread : public QThread{

public:
    OpenerThread();

    void run() override
    {
        CoInitialize(0);
        CoInitializeEx(NULL, COINIT_MULTITHREADED);

        ExcelManager::openExcelFile(); // This works successfully.
    }
};

ReadManagerThread.h

#include <QThread>
#include <Ole2.h>
#include "ExcelManager.h"

class ReadManagerThread : public QThread{

public:
    ReadManagerThread();

    void run() override
    {
        CoInitialize(0);
        CoInitializeEx(NULL, COINIT_MULTITHREADED);

        ExcelManager::setFileRowCount(); // This results in error.

        // Proceed to read and extract data.
    }
};

这两个线程通过以下代码在我的一个类中开始:

OpenerThread* openerThread = new OpenerThread();
ReadManagerThread* readManagerThread = new ReadManagerThread();
openerThread->start();

connect(openerThread, SIGNAL(finished()),
        readManagerThread, SLOT(start()));

更新: 经过大量研究,我明白不可能在不同线程之间共享一个 QAxObject*。换句话说,只有创建 QAxObject 的线程才能使用它。建议创建一个 QThread 并在其中打开 Excel 文件,然后在该线程中创建必要的插槽,然后从其他线程发出信号。这样,多个线程可以访问 COM 对象,而无需直接调用它。当我实现这个目标时,我会更新这篇文章。

4

0 回答 0