如何在QT中处理C# COM事件?

3

我有一个简单的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)]来解决上述问题(有关详细信息,请参见注释)

运行代码时,我遇到以下错误:

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

我的问题是,如何在COM和QT中处理事件/委托?
背景信息如下:
如果COM对象实现了IDispatch接口,则该对象的属性、方法和事件将作为Qt属性、槽和信号可用。
我已经使用以下资源进行了研究:
- 处理C# COM事件的C++方法 - 如何在托管代码中放置IDispatch* - 如何在C++中触发C# COM事件?
请帮忙!

不了解生成的.h文件,听起来你的实现过于可见。CompletedDelegate 类型根本不应该可见。项目 > 属性 > 应用选项卡 > 程序集信息按钮,取消选择“使程序集对 COM 可见”的选项。仅在应该可见的声明(接口和类)上应用 [ComVisible(true)] 特性。或者在委托上应用 [ComVisible(false)]。 - Hans Passant
谢谢@HansPassant,这确实解决了我面临的错误攻击。虽然现在它可以编译并调用方法_Add(int, int)_,但我仍然无法实例化和访问事件_Completed_,也不确定如何做到这一点。我尝试过connect(&eventClass, SIGNAL(Completed()), this, SLOT(test()));,但那似乎不正确。 具体来说,我得到的错误是:**QObject::connect: No such signal MyEventClassLibrary::Calculator::Completed()**。 - Anduril28
你已经知道了这个问题的解决方案。请发布答案并接受它,以完成问答环节。然后点击“提问”按钮,寻求下一个问题的帮助。 - Hans Passant
如果需要的话,我可以这样做,但我提出的问题是“如何在COM和QT中处理事件/委托?”修复大量错误是一个问题,但那不是我主要的问题。我可以用这个新信息更新问题描述。 - Anduril28
1个回答

1
这个问题有两个部分,目的是让一个C# COM-visible事件在QT中触发:
  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)));

谢谢!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接