PDA

View Full Version : Qt for Excel/VBA



Nightfox
12th December 2012, 13:15
I'm trying to build a function package (.dll) for excel that can be used through the VBA module. I want to expose two basic functions to VBA, one that returns the product of two number (called Multiply) and one that shows some GUI (called ShowDialog). Now there're several ways to export functions with Qt+MinGW, which is my setup. I have chosen to compile a c file with a .def file listing the exported functions.
For testing reasons, I've build the library from two IDEs, one from Visual C++ 6 and one from Qt. The VC6 works perfectly when I connect to it from Excel/VBA but the Qt won't even load the library - and I can't figure out why?!
When I look at the two .dlls with Depenency Walker they both export the two functions undecorated (see attached screenshot), so the they appear to have the same binary interface.
When I load them with QLibrary they also behave the same.

I don't think it's the different compiler settings since I've followed these instructions
http://sourceware.org/binutils/docs/ld/WIN32.html
http://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/

It might be that the windows SDK isn't included properly, so I turned to this article
http://doc.qt.digia.com/solutions/4/qtwinmigrate/winmigrate-walkthrough.html
which didn't help.

I'm kinda stuck here, guys! Has anyone succeeded in writing a Qt dll for Excel/VBA?

amleto
12th December 2012, 16:26
vc6 is so old it. It is not a compliant c++ compiler and you should not be using it if you are programming in c++ now.

There is no such thing as a Qt dll in this sense. You can make a dll from c++ code, and the compatibility, or otherwise, with excel etc will have little to do with Qt.

In your case, the dll that 'isn't working' was built with minGW. Are you sure the def files are the same for vc6 and gcc?

Nightfox
12th December 2012, 19:12
vc6 is so old it. It is not a compliant c++ compiler and you should not be using it if you are programming in c++ now.
Note that I simply supplied the VC6 for demonstration purposes. As you can see it works fine. I have not tested with later version of visual studio as I only have license for VC6 and normally use Qt exclusively.

There is no such thing as a Qt dll in this sense. You can make a dll from c++ code, and the compatibility, or otherwise, with excel etc will have little to do with Qt.
Qt actually supports three different library types, plugin, static and shared ( .dll on windows ). I'm using the latter but this should be clear from the keyword "lib" in the Qt project' .pro file.

In your case, the dll that 'isn't working' was built with minGW. Are you sure the def files are the same for vc6 and gcc?
I've attached both projects with full source code in the post, were you not able to open them? Please do and you'll see two identical .def files. Use the link I provided to see that MinGW also supports .def approach to export functions.

amleto
12th December 2012, 19:49
your def file isnt in same location as dll for qt case. Dunno. using def files is antiquated. I've never used that approach.

Why don't you make a simple app to use the dlls you have made? Then you can debug from there rather than vba/excel

Nightfox
12th December 2012, 20:15
I made a Qt test application that loads the two different .dll using QLibrary. They behave that same. Also, they have the same binary interface as you can see from the Dependency Walker screenshot.

I could be great to hear from somebody that have succeeded in running Qt dll from Excel/VBA.

amleto
12th December 2012, 20:27
the dll and the .a do not have the same filename. This might be an issue? Don't know if a lookup for libxxx.a is always automatic on windows

You're also comparing debug vc6 build with release mingw build.

Nightfox
12th December 2012, 20:44
There's no .a file?! .a is the extension of a static library, I'm compiling both as shared .dll
Debug/Release mode is irrelevant for this comparison.
Look, my problem is to figure out why Excel/VBA will accept the VC6 .dll and not the Qt .dll. They should be exactly the same but they're not.

d_stranz
12th December 2012, 22:39
Look, my problem is to figure out why Excel/VBA will accept the VC6 .dll and not the Qt .dll. They should be exactly the same but they're not.

Why do you think they should be exactly the same? You're using two different compilers, which more than likely have different conventions for the name mangling that occurs during compilation. So, since your VC6 DLL was built using the same compiler that MS uses to create VBA, the name mangling is the same. You many have defined the methods inside them the same way, but I doubt if they look the same from VBA's viewpoint. If your .def file contains the names as generated from VC6, then it is likely incorrect to try to use it with the mingw-generated DLL. I do not know how to use mingw, but there should be a way to determine the names of symbols exported from a DLL.

A second issue is that a Qt DLL needs a running QApplication event loop in order to receive and process Qt events. This certainly isn't being supplied by VBA, so where is it coming from?

amleto
12th December 2012, 22:47
he's compiling .c files as c code. There is no (c++) mangling.




There's no .a file?! .a is the extension of a static library, I'm compiling both as shared .dll
Debug/Release mode is irrelevant for this comparison.
Look, my problem is to figure out why Excel/VBA will accept the VC6 .dll and not the Qt .dll. They should be exactly the same but they're not.

There IS a .a file in your qt release folder that contains the .dll. This is probably analogous to the .lib file that msvc c++ compiler makes when building a .dll that has exported symbols.

As for debug/release... I find that when you try to tackle a problem it helps to reduce all controllable differences. The fact that these should have been built with different CRT could be a crucial factor. You can't know for sure until you *eliminate* it as a variable. Please, if you are going to pedal the line 'they should be exactly the same', let's not overlook something as significant as debug vs release.

Nightfox
13th December 2012, 11:39
Why do you think they should be exactly the same? You're using two different compilers, which more than likely have different conventions for the name mangling that occurs during compilation.
Although it's posible to export C++ functions from a DLL, I want to avoid doing so because it doesn't have the well defined application binary interface that C does. Which is why I'm using .C files as pointed by amleto.


A second issue is that a Qt DLL needs a running QApplication event loop in order to receive and process Qt events. This certainly isn't being supplied by VBA, so where is it coming from?
Please note that the source code doesn't contain any QObjects so no event loop needed.


Please, if you are going to pedal the line 'they should be exactly the same', let's not overlook something as significant as debug vs release.
You're absolutely right, all stones should be turned. I compiled the Qt source in debug mode but still no success.

I had a closer look to the dependency walker. The VC6 (VC6DLL4VBA.dll) has a size of 201KB where the Qt (QTDLL4VBA.dll) only has a size of 19KB. Both in debug mode. The significant size difference made me look closer to dependency walker and at first sight, both of the libraries depend on KERNEL32 and USER32, but Qt depends on a third library that VC6 doesn't - the Microsoft C run time library (MSVCRT.DLL). I don't know why it's included in the Qt dll and not in the VC6?
But more interesting, it seem like the KERNEL32 include from the VC6 dll contain way more functions than the Qt dll that only contains two? WTF!?? Why am I only including a fraction of the KERNEL32? Seems like I'm opening a wormbox!

Any ideas to progress from here?