Solved IDL (and therefore tlb) file generation for COM shared libraries
-
Hi,
I'm trying to use Qt/C++ for a project which will be used for .NET and Delphi. As C++/CLI wrapper is only good for .NET I need to find a better way, which seems like ActiveQt. I've investigated the examples and almost get everything about it. But there is a strange thing.
If I build a simple QAxServer example with the settings "TEMPLATE = lib" for creating a dll, the compiler whines about the missing idl file, which could not be created due to missing "DumpIDL" meta object information.
If I simply change the template to "TEMPLATE = app". I get an exe and a fully successful compile with both idl and tlb files.
Here's the code I'm testing.
QT -= gui QT += axserver TARGET = Foo TEMPLATE = app SOURCES += foo.cpp HEADERS += foo.h RC_FILE = Foo.rc target.path = . INSTALLS += target
Foo.h
#pragma once #include <QObject> class Foo : public QObject { Q_OBJECT Q_CLASSINFO("ClassID", "{A4C17D65-7896-4214-8679-74BE1CE2B35E}") Q_CLASSINFO("InterfaceID", "{B743C617-81D8-4015-BD38-4E1F671388F3}") public: Foo(QObject *parent = nullptr); ~Foo(); };
Foo.cpp
#include <QAxFactory> #include "foo.h" QAXFACTORY_BEGIN("{A17FF66F-97EB-42F8-A95F-16E0395A0B7E}", "{D2385374-5F51-4950-BEB7-C5EC4D0F527C}") QAXCLASS(Foo) QAXFACTORY_END() Foo::Foo(QObject *parent) { (void)parent; } Foo::~Foo() { }
Foo.rc
1 TYPELIB "Foo.rc"
I know I can use the exe as a dll but there are some caveats. AFAIK importing exe methods are slower than importing dll methods.
Thanks in advance.
-
Looks like qmake is not running idc automatically. can you try running it manually and see if that works?
Just a note (never tested) documentation states that Borland Delphi is not supported as client don't know if it's just the pre-embarcadero or even the new one but be aware of it -
Hi @VRonin,
qmake is running the idc tool fine. I had approved that with calling the tool manually. Got the same error message.
The size of the final image is also quite different for a simple test code. Probably compiler is not putting some relevant information (metadata, i guess) into the image, but why? I'm just changing the template and rerunning the build process cleanly (otherwise the idc tool finds the old idl file and completes successfully).
Regarding to the other statement, I'm also curious about the result with Delphi. As I couldn't export the methods and types properly yet, not have seen the final result (I'm open to the ideas. Doing almost the same thing with 'comapp' example but can not get them on the otherside. comapp is fine). Maybe the "not working" side was the widgets side. I won't be using any UI therefore may get away from it. Do you know how to exclude QWidgets dependency? (Although, I've investigated the ActiveQt code and seen the dependency to QWidgets inside, no matter necessary or not.)
-
Also I've confirmed it with opening the final images via a hex editor (exe and dll). The information is really not there (dll). Smells like a bug, isn't it?
-
Note: using "Q_INVOKABLE" macro for the methods made them visible in the COM assembly.
-
Let me answer my question.
You need to add a def file to your build process:
Add this line to Foo.pro:
DEF_FILE = Foo.def
And create a Foo.def including these lines:
EXPORTS DllCanUnloadNow PRIVATE DllGetClassObject PRIVATE DllRegisterServer PRIVATE DllUnregisterServer PRIVATE DumpIDL PRIVATE
In the "app" template, these information is automatically put in the final image, but if you choose to create a dynamic library, you have to tell the compiler that you need them explicitly.