【问题标题】:How to handle C# COM events in QT?如何在 QT 中处理 C# COM 事件?
【发布时间】:2017-02-04 04:43:13
【问题描述】:

我有一个简单的 C# COM 可见库,如下所示:

namespace MyEventClassLibrary {

[Guid("0ab09e18-bf85-48c8-a45d-a0cebed77a5c")]
public interface ICalculator
{
    int Add(int Num1, int Num2);
}

[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("9e09b634-8c1a-4926-83b2-f6f988595c85")]
public interface ICalculatorEvents
{
    [DispId(1)]
    void Completed(int Result);
}

[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(ICalculatorEvents))]
[Guid("6cebc4db-2e8f-4e24-91a5-24ffdf97fc6a")]
public class Calculator : ICalculator
{
    [ComVisible(false)]
    public delegate void CompletedDelegate(int result);

    public event CompletedDelegate Completed;

    public int Add(int Num1, int Num2)
    {
        int Result = Num1 + Num2;
        if (Completed != null)
            Completed(Result);

        return Result;
    }
}}

我已注册并将 .TLB 导入 QT:

TYPELIBS = ..\MyEventClassLibrary\MyEventClassLibrary\bin\Debug\MyEventClassLibrary.tlb

我的 mainwindow.cpp 文件看起来像:

#include <QDebug>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "myeventclasslibrary.h" 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    MyEventClassLibrary::Calculator eventClass;
    connect(&eventClass, SIGNAL(Completed()), this, SLOT(test()));

    qDebug() << eventClass.Add(1,2);
}

void MainWindow::test()
{
    qDebug() << "Here";
}

MainWindow::~MainWindow()
{
    delete ui;
}

当我在 QT 中构建项目时,我遇到了 40 多个问题:

MyEventClassLibrary.h:144: error: C2535: 'MyEventClassLibrary::CompletedDelegate::CompletedDelegate(void)': member function already defined or declared

MyEventClassLibrary.h:147: error: C2065: 'iface': undeclared identifier

已通过将 [ComVisible(false)] 添加到委托来解决上述问题(请参阅 cmets 了解更多信息)

当我运行代码时出现以下错误:

QObject::connect: No such signal MyEventClassLibrary::Calculator::Completed()

我的问题是,您如何处理 COM 和 QT 中的事件/委托?

作为背景信息,QT 文档说:

如果 COM 对象实现了 IDispatch 接口,则该对象的属性、方法和事件将作为 Qt 属性、槽和信号可用。

我使用以下资源和研究:

Handle C# COM events in C++

how to put IDispatch* in managed code

How to fire c# COM events in c++?

还有更多;请帮忙!

【问题讨论】:

  • 在对生成的 .h 文件一无所知的情况下,听起来您的实现太多了。 CompletedDelegate 类型根本不应该是可见的。项目 > 属性 > 应用程序选项卡 > 装配信息按钮并取消选中“使装配 COM 可见”选项。仅在应该可见的声明、接口和类上应用 [ComVisible(true)] 属性。或者在委托上应用 [ComVisible(false)]。
  • 感谢@HansPassant,这确实解决了我面临的大量错误。虽然它现在可以编译并且我可以调用方法Add(int, int),但我仍然无法并且不确定如何实例化和访问事件Completed。我试过connect(&amp;eventClass, SIGNAL(Completed()), this, SLOT(test()));,但这似乎不正确。具体来说,我得到的错误是:QObject::connect: No such signal MyEventClassLibrary::Calculator::Completed()
  • 你知道这个问题的解决方案。因此,通过发布答案并接受它来完成 Q+A。然后点击按钮寻求帮助解决您的下一个问题。
  • 如果有必要我可以这样做,但我问的问题是“你如何处理 COM 和 QT 中的事件/委托?”。修复大量错误是一个问题,但这不是我的主要问题。不过,我可以用这些新信息更新问题正文。

标签: c# c++ qt com


【解决方案1】:

这个问题分为两部分,目标是在 QT 中触发 C# COM 可见事件:

  1. 当我最初构建 QT 应用程序时,由于委托可见,我遇到了 40 多个错误。 通过在委托声明上方添加 [ComVisible(false)] 解决了这个问题 谢谢@HansPassant。

  2. 解决此问题后,我尝试将一个 SLOT 连接到 COM SIGNAL,但 QT 说它找不到 Completed 事件。 这是通过匹配函数原型解决的; Completed有一个参数int,我没有在SLOT函数中包含int。 (德普)

我原来的连接是:

connect(&eventClass, SIGNAL(Completed()), this, SLOT(test()));

应该是:

connect(&eventClass, SIGNAL(Completed(int)), this, SLOT(test(int)));

谢谢!

【讨论】:

    猜你喜欢
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    • 2019-06-16
    • 2014-09-29
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多