c++ - QAxBase::dynamicCallHelper:对象不支持自动化
问题描述
我正在尝试使用 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 对象,而无需直接调用它。当我实现这个目标时,我会更新这篇文章。
解决方案
推荐阅读
- perl - Parse::RecDescent 和语法
- xml - 我正在尝试“嵌套” xsl:for-each (我认为)
- css-float - 为什么在 css 上应用浮点数时 div 元素被压扁?
- angular - Karma 或 TypeScript 编译器告诉我“字符串”类型上不存在属性“padStart”
- awk - 为什么有几个 Linux 发行版默认提供 mawk,即使它不符合 POSIX 标准?
- javascript - 如何通过按钮onpress从函数调用中返回值?
- html - 您如何在网站标题/英雄上创建非矩形图像?
- c++ - 如何在 C++ 中存储更多“复杂数据”(映射、类、结构、指针)?
- google-bigquery - 如何使用正则表达式在 BigQuery 中使用最后一次出现的正斜杠进行拆分
- python - Python 随机森林回归器在 nan 值上出错,尽管已删除