.Net COM and ActiveQt: return class instance doesn't work
-
Hello,
For a project i'm getting familliar with .net COM and ActiveQt.
I'm able to get result from functions that are returning standard types (string, int...)But returning a new instance of a class doesn't work:
my .net file .cs (.Net framework 4.8)
using System.Runtime.InteropServices; namespace COMTest { [ComVisible( true )] [Guid( "BAD219A5-CE0A-40EB-BC66-9C6D3B71F084" )] [ClassInterface( ClassInterfaceType.AutoDual )] public class COMTestSubclass { public string AGetString() { return "COMTestSubclass::AGetString()"; } } [ComVisible( true )] [Guid( "05E563DB-EAA8-4C45-96DD-9A7B83CA1F63" )] [ClassInterface( ClassInterfaceType.AutoDual )] public class COMTestMain { public COMTestSubclass AGetSubclass() { return new COMTestSubclass(); } public string AGetString() { return "COMTestMain::AGetString()"; } } }
my main.cpp file, comtest.h was generated by dumpcpp and the tlb file (Qt 6.3.0)
#include <QApplication> #include "comtest.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qInfo() << "Main:"; COMTest::COMTestMain *main = new COMTest::COMTestMain(); qInfo() << main->AGetString(); qInfo() << main->ToString(); qInfo() << "\n"; qInfo() << "SubClass:"; COMTest::COMTestSubclass *subclass = new COMTest::COMTestSubclass(); qInfo() << subclass->AGetString(); qInfo() << subclass->ToString(); qInfo() << "\n"; qInfo() << "SubClassPtr:"; auto subclassPtr = main->AGetSubclass(); qInfo() << subclassPtr->AGetString(); qInfo() << subclassPtr->ToString(); return 0; }
16:55:07: Starting C:\Users\ME\Desktop\MixedInKeyTools\COMTest\build-QtCOMTest-Desktop_Qt_6_3_0_MinGW_64_bit-Debug\debug\QtCOMTest.exe... Main: "COMTestMain::AGetString()" "COMTest.COMTestMain" SubClass: "COMTestSubclass::AGetString()" "COMTest.COMTestSubclass" SubClassPtr: "" 16:55:08: C:\Users\ME\Desktop\MixedInKeyTools\COMTest\build-QtCOMTest-Desktop_Qt_6_3_0_MinGW_64_bit-Debug\debug\QtCOMTest.exe crashed.
As you can see COMTestSubclass can be instanciated from C++, but not when returned from .net.
I tried using Interface, but same result.What am i doing wrong ?
Thanks in advance for your help.
-
Hi, the cs file is most likely ok, but the dumpcpp utility that gives you the comtest.h file is a bit lacking when it comes to returning new class instances, so. the crash occurs because that class pointer is an orphan i.e. it tries to exist without belonging to a QAxObject.
One solution could be to create the COM object via a detour through a QAxObject and IDispatch, try this:
qInfo() << "SubClassPtr:"; auto subclassPtr = (COMTest::COMTestSubclass*) main->querySubObject("AGetSubclass"); qInfo() << subclassPtr->AGetString(); qInfo() << subclassPtr->ToString();
that should make sure that subclassPtr belongs to a QAxObhect and not crash :-)
-
Hello,
That worked perfectly thank you !
I also saw and tested that i can give querySubObject parameters.setProperty seems to be able to set a member variable (but it needs to be public in the cs).
But i don't see any GetProperty (which is not really a problem since i can make a getter).But what is dynamicCall for ?
-
Hi, re. getProperty() you've spent too much time in Microsoft-land :-)
Qt uses the noun/setnoun standard, so for getting something:
subclassPtr->property("ToString");
Apart from property/setProperty there are two flavors of COM calls you can issue from your QAxObject classes:
- dynamicCall() is like a superset of setProperty(), it's used when more than 1 argument is needed
- querySubObject() is used mostly when navigating a hierarchy of COM objects, for example stepping dowm into an Excel spreadsheet.
(Also there's the propertyBag()/setPropertyBag() pair to get/set all the properties in one fell swoop, but I've never tried them)