【发布时间】: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 属性、槽和信号可用。
我使用以下资源和研究:
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(&eventClass, SIGNAL(Completed()), this, SLOT(test()));,但这似乎不正确。具体来说,我得到的错误是:QObject::connect: No such signal MyEventClassLibrary::Calculator::Completed() -
你知道这个问题的解决方案。因此,通过发布答案并接受它来完成 Q+A。然后点击按钮寻求帮助解决您的下一个问题。
-
如果有必要我可以这样做,但我问的问题是“你如何处理 COM 和 QT 中的事件/委托?”。修复大量错误是一个问题,但这不是我的主要问题。不过,我可以用这些新信息更新问题正文。