[英]Instantiation of QAxObject from dumpcpp segfault with minGw C++ -o2 or -o3 flag
Qt 版本:5.12.10
我想與一個使用 COM 層的應用程序交互,這個應用程序是用一個 .tlb 文件交付的,所以我使用 Qt 的 dumpcpp 來生成 header 和源文件。
要使用生成的 class,我首先從 windows ROT 獲得 IUnknown,然后從 class 實例化我需要的類,我使用了一個接口。
我的代碼如下所示:
實例化我的 class 的代碼:
//Initialize COM, load the ROT, get the monikers and for each monikers
//Check if the monikers name is the one we want
if (!wcsncmp(monikerDisplayName, appComIdentifier, wcslen(appComIdentifier)))
{
qDebug() << "Found app";
IUnknown *currentObject = nullptr;
if (rot->GetObject(currentMoniker, ¤tObject) == S_OK)
{
AppCommunication appCom(static_cast<app::IApplicationInterface *>(new QAxObject(currentObject)));
}
}
AppCommunication class:
Header 文件:
class AppCommunication : public IAppCommunication
{
public:
AppCommunication(app::IApplicationInterface *applicationInterface);
~AppCommunication() override = default;
private:
app::appApplication appApplication;
app::appJob appJob;
};
cpp文件:
AppCommunication::AppCommunication(app::IApplicationInterface *applicationInterface)
: appApplication(applicationInterface),
appJob(static_cast<app::IJobInterface *>(new QAxObject(appApplication.CreateJobObject())))
// ^
// |
// Segfault here
{
}
app命名空間下的所有類都是dumpcpp工具生成的。
這與編譯器中的優化標志 -o0 或 -o1 完美配合,但是當我設置 -o2 或 -o3 時,我的程序崩潰了。
據我所知,這是導致崩潰的 appJob 的實例化(而不是 JobInterface 的獲取)。
我認為 Qt 的代碼和 Qt 生成的代碼足夠健壯/經過驗證,所以我認為這個錯誤一定是我有未定義的行為。 但我看不出我在這里做錯了什么。
編輯:我設法找到一種方法來避免這個問題。 我發現如果我使用指針而不是 class 本身它工作正常:
Header 文件:
class AppCommunication : public IAppCommunication
{
public:
AppCommunication(app::IApplicationInterface *applicationInterface);
~AppCommunication() override = default;
private:
app::appApplication appApplication;
app::appJob *appJob;
};
cpp文件:
AppCommunication::AppCommunication(app::IApplicationInterface *applicationInterface)
: appApplication(applicationInterface),
appJob(new app::appJob(static_cast<app::IJobInterface *>(new QAxObject(appApplication.CreateJobObject()))))
{
}
這也適用於 unique_ptr 而不是原始指針,所以這是我將采取的路線。
我越來越開始認為這是一個 MinGW,因為我看不出是什么導致了這樣的問題......
錯誤在我身上。
從 COM 獲取 IUnknown * 后,我們必須從中獲取 IDispatch * 然后直接實例化類:
//Initialize COM, load the ROT, get the monikers and for each monikers
//Check if the monikers name is the one we want
if (!wcsncmp(monikerDisplayName, appComIdentifier, wcslen(appComIdentifier)))
{
qDebug() << "Found app";
IUnknown *currentObject = nullptr;
if (rot->GetObject(currentMoniker, ¤tObject) == S_OK)
{
//Add the get dispatch part
IDispatch *currentObjectDispatch = nullptr;
HRESULT hr = currentObject->QueryInterface(IID_IDispatch, (void **)¤tObjectDispatch);
if (FAILED(hr))
{
return;
}
//Get the interface directly without static cast
AppCommunication appCom(new app::IApplicationInterface(currentObjectDispatch));
// Use the class instance with some method calls
}
}
並對我們在 ctor 中檢索到的 class 執行相同的操作:
AppCommunication::AppCommunication(app::IApplicationInterface *applicationInterface)
: appApplication(applicationInterface),
appJob(new app::IJobInterface(appApplication.CreateJobObject()))
{
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.