Help using an hello world DLL (that might be at fault)
-
I'm really an embedded software engineer who has created many simple Qt apps over the years for things like production tests, bootloader GUIs and the like. So, I basically know what I'm doing creating Qt apps when I used Qt libraries, but am no GUI or C++ expert.
I'm trying to create what will be a fairly simple DLL, even when finished, and use it in Qt Creator. I've followed a tutorial and created a DLL in Visual Studio. It's very basic just to prove I can create even the most simple DLL. For the moment, the DLL does nothing but return a version:
char* GetVersion2(void) { return (char*)VERSION_STRING; }I've then created a Qt GUI just to try and use this simple DLL, but despite reading many tutorials I'm struggling to get it to work.
I have put in my .pro file
INCLUDEPATH += "C:/Software/DLL/CTR6500/CTR6500/"
This is where the header file lives.
INCLUDEPATH += "C:/Software/DLL/CTR6500/CTR6500/x64/Debug/"
This is where the DLL lives.
And finally
LIBS += -lCTR6500
CTR6500.dll is the name of the DLL I created.
I do
#include "CTR6500.h"
inside mainwindow .cpp
And at first it complains saying
C:\Software\Qt\DLLTest\dllTest\mainwindow.cpp:2: warning: Included header CTR6500.h is not used directly (fix available)
I can click on the fix and it juist removes the include line. This seems weird as I can include other header files and it doesn't whinge about them not being used.
If I do not remove the #include "CTR6500.h" line, in a function called testTheDLL():
I can do this:
ui->debugEdit->appendPlainText(GetVersion2());
It is happy about the use of GetVersion2() and indeed it will auto complete GetVersion2 if I start typing it. So it would appeear it's basically happy with finding that function.
But I get an error:
:-1: error: collect2.exe: error: ld returned 1 exit status
Which I can see from a web search means there is an issue somewhere else, but there is no other error or warning.
I appreciate I am likely doing something stupid or naive and this might be a little bit beyond the scope of a Qt forum, but if not, anyone able to help me here please and work out what I might be doing wrong please?
Many thanks.
-
I'm really an embedded software engineer who has created many simple Qt apps over the years for things like production tests, bootloader GUIs and the like. So, I basically know what I'm doing creating Qt apps when I used Qt libraries, but am no GUI or C++ expert.
I'm trying to create what will be a fairly simple DLL, even when finished, and use it in Qt Creator. I've followed a tutorial and created a DLL in Visual Studio. It's very basic just to prove I can create even the most simple DLL. For the moment, the DLL does nothing but return a version:
char* GetVersion2(void) { return (char*)VERSION_STRING; }I've then created a Qt GUI just to try and use this simple DLL, but despite reading many tutorials I'm struggling to get it to work.
I have put in my .pro file
INCLUDEPATH += "C:/Software/DLL/CTR6500/CTR6500/"
This is where the header file lives.
INCLUDEPATH += "C:/Software/DLL/CTR6500/CTR6500/x64/Debug/"
This is where the DLL lives.
And finally
LIBS += -lCTR6500
CTR6500.dll is the name of the DLL I created.
I do
#include "CTR6500.h"
inside mainwindow .cpp
And at first it complains saying
C:\Software\Qt\DLLTest\dllTest\mainwindow.cpp:2: warning: Included header CTR6500.h is not used directly (fix available)
I can click on the fix and it juist removes the include line. This seems weird as I can include other header files and it doesn't whinge about them not being used.
If I do not remove the #include "CTR6500.h" line, in a function called testTheDLL():
I can do this:
ui->debugEdit->appendPlainText(GetVersion2());
It is happy about the use of GetVersion2() and indeed it will auto complete GetVersion2 if I start typing it. So it would appeear it's basically happy with finding that function.
But I get an error:
:-1: error: collect2.exe: error: ld returned 1 exit status
Which I can see from a web search means there is an issue somewhere else, but there is no other error or warning.
I appreciate I am likely doing something stupid or naive and this might be a little bit beyond the scope of a Qt forum, but if not, anyone able to help me here please and work out what I might be doing wrong please?
Many thanks.
@DiBosco
I don't use Windows much these days, so you may get a clearer answer from someone else. But you do not put the directory of your DLL intoINCLUDEPATH, that helps nothing. You do that for the.hfile. When you built your DLL you should have also got a.libfile. You need to link against that to use the DLL (statically, as opposed to dynamically at runtime, which is a different thing). So its directory needs to be added to yourLIBSvariable, so it can find the.libfor the-lCTR6500.It might be that
LIBS += -L\path\to\lib\directory -lCTR6500works? (Can't remember whether a space is wanted after the
-L?).To test all is well if that does not work, I think you can try
LIBS += \path\to\lib\directory\CTR6500.lib # actual full path to the .lib file itselfThat avoids thinking about
-Land-larguments. It's better to get them right in the long run and use-L/-l, but this might at least show you are on the right track.Finally, the DLL itself needs to be found (only) at runtime. It must either be on your
PATHor in the same directory as your executable which wants to use it.HOWEVER I now notice a nasty wrinkle in what you have said:
and created a DLL in Visual Studio.
:-1: error: collect2.exe: error: ld returned 1 exit status
I think you have a complete mismatch here. If you built a DLL in VS I imagine you were using the MSVC compiler for that, right? But the error message from
collect2/ldshows you must be using the alternative MinGW compiler/linker. (The MSVC linker is namedLINKand would not produce this message.) That will never work. You must use either MSVC or MinGW for all the stuff you want to compile/link together, you cannot mix and match, and I think you have your Qt Creator set up to use a MinGW kit while your VS is using MSVC, right? -
@DiBosco
I don't use Windows much these days, so you may get a clearer answer from someone else. But you do not put the directory of your DLL intoINCLUDEPATH, that helps nothing. You do that for the.hfile. When you built your DLL you should have also got a.libfile. You need to link against that to use the DLL (statically, as opposed to dynamically at runtime, which is a different thing). So its directory needs to be added to yourLIBSvariable, so it can find the.libfor the-lCTR6500.It might be that
LIBS += -L\path\to\lib\directory -lCTR6500works? (Can't remember whether a space is wanted after the
-L?).To test all is well if that does not work, I think you can try
LIBS += \path\to\lib\directory\CTR6500.lib # actual full path to the .lib file itselfThat avoids thinking about
-Land-larguments. It's better to get them right in the long run and use-L/-l, but this might at least show you are on the right track.Finally, the DLL itself needs to be found (only) at runtime. It must either be on your
PATHor in the same directory as your executable which wants to use it.HOWEVER I now notice a nasty wrinkle in what you have said:
and created a DLL in Visual Studio.
:-1: error: collect2.exe: error: ld returned 1 exit status
I think you have a complete mismatch here. If you built a DLL in VS I imagine you were using the MSVC compiler for that, right? But the error message from
collect2/ldshows you must be using the alternative MinGW compiler/linker. (The MSVC linker is namedLINKand would not produce this message.) That will never work. You must use either MSVC or MinGW for all the stuff you want to compile/link together, you cannot mix and match, and I think you have your Qt Creator set up to use a MinGW kit while your VS is using MSVC, right?@JonB said in Help using an hello world DLL (that might be at fault):
I think you have a complete mismatch here. If you built a DLL in VS I imagine you were using the MSVC compiler for that, right? But the error message from collect2/ld shows you must be using the alternative MinGW compiler/linker. (The MSVC linker is named LINK and would not produce this message.) That will never work. You must use either MSVC or MinGW for all the stuff you want to compile/link together, you cannot mix and match, and I think you have your Qt Creator set up to use a MinGW kit while your VS is using MSVC, right?
Yes, this is the case. Generally I use Linux for everything and the compiler is obviously set up by the install from the repositories, but with Windows I can never get MSVC to work, whereas mingw does work without a hitch.
That issue of mismtaches throws up a question that seems like it is going to be a huge problem in general. If you're releasing a DLL out into the wild, surely you don't need a different one for each compiler that is being used? I thought you were providing a binary that any development enviroment in any language could use?
**Edit:
LIBS += -L\path\to\lib\directory -lCTR6500
Has made it work**
-
@JonB said in Help using an hello world DLL (that might be at fault):
I think you have a complete mismatch here. If you built a DLL in VS I imagine you were using the MSVC compiler for that, right? But the error message from collect2/ld shows you must be using the alternative MinGW compiler/linker. (The MSVC linker is named LINK and would not produce this message.) That will never work. You must use either MSVC or MinGW for all the stuff you want to compile/link together, you cannot mix and match, and I think you have your Qt Creator set up to use a MinGW kit while your VS is using MSVC, right?
Yes, this is the case. Generally I use Linux for everything and the compiler is obviously set up by the install from the repositories, but with Windows I can never get MSVC to work, whereas mingw does work without a hitch.
That issue of mismtaches throws up a question that seems like it is going to be a huge problem in general. If you're releasing a DLL out into the wild, surely you don't need a different one for each compiler that is being used? I thought you were providing a binary that any development enviroment in any language could use?
**Edit:
LIBS += -L\path\to\lib\directory -lCTR6500
Has made it work**
-
@JonB said in Help using an hello world DLL (that might be at fault):
I think you have a complete mismatch here. If you built a DLL in VS I imagine you were using the MSVC compiler for that, right? But the error message from collect2/ld shows you must be using the alternative MinGW compiler/linker. (The MSVC linker is named LINK and would not produce this message.) That will never work. You must use either MSVC or MinGW for all the stuff you want to compile/link together, you cannot mix and match, and I think you have your Qt Creator set up to use a MinGW kit while your VS is using MSVC, right?
Yes, this is the case. Generally I use Linux for everything and the compiler is obviously set up by the install from the repositories, but with Windows I can never get MSVC to work, whereas mingw does work without a hitch.
That issue of mismtaches throws up a question that seems like it is going to be a huge problem in general. If you're releasing a DLL out into the wild, surely you don't need a different one for each compiler that is being used? I thought you were providing a binary that any development enviroment in any language could use?
**Edit:
LIBS += -L\path\to\lib\directory -lCTR6500
Has made it work**
@DiBosco said in Help using an hello world DLL (that might be at fault):
if you're releasing a DLL out into the wild, surely you don't need a different one for each compiler that is being used? I thought you were providing a binary that any development enviroment in any language could use?
Yes and No :) Again, my knowledge for Windows may not be perfect :) I believe you will find you have only been able to successfully "cross-link" between MSVC & MinGW because the content of your DLL is pure C? If/when you try to make the DLL content be C++ I believe the link will fail (for sure if it exports a class with methods, the "name mangling" won't work). Depends whether you are intending to do that! You could make your DLL be C++ now, temporarily, and verify if I am correct! Then you will know going forward.
It may be that a Windows Qt-er chimes in here to give you more clarity, I think I have said what I think I know ;-)
-
@DiBosco said in Help using an hello world DLL (that might be at fault):
if you're releasing a DLL out into the wild, surely you don't need a different one for each compiler that is being used? I thought you were providing a binary that any development enviroment in any language could use?
Yes and No :) Again, my knowledge for Windows may not be perfect :) I believe you will find you have only been able to successfully "cross-link" between MSVC & MinGW because the content of your DLL is pure C? If/when you try to make the DLL content be C++ I believe the link will fail (for sure if it exports a class with methods, the "name mangling" won't work). Depends whether you are intending to do that! You could make your DLL be C++ now, temporarily, and verify if I am correct! Then you will know going forward.
It may be that a Windows Qt-er chimes in here to give you more clarity, I think I have said what I think I know ;-)
@JonB said in Help using an hello world DLL (that might be at fault):
@DiBosco said in Help using an hello world DLL (that might be at fault):
if you're releasing a DLL out into the wild, surely you don't need a different one for each compiler that is being used? I thought you were providing a binary that any development enviroment in any language could use?
Yes and No :) Again, my knowledge for Windows may not be perfect :) I believe you will find you have only been able to successfully "cross-link" between MSVC & MinGW because the content of your DLL is pure C? If/when you try to make the DLL content be C++ I believe the link will fail. Depends whether you are intending to do that! You could make your DLL be C++ now, temporarily, and verify if I am correct! Then you will know going forward.
It may be that a Windows Qt-er chimes in here to give you more clarity, I think I have said what I think I know ;-)
That is a very good question/point. As things stand, yes the dll just has C functions in it. The tutorial I based this on did set the project up as C++, but said tutorial instructs you to put:
extern "C" CTR6500_API
In front of each of your functions in the header file.
I had just assumed C and C++ were interchangeable here but it does look like C, not C++ in the source files.
-
@JonB said in Help using an hello world DLL (that might be at fault):
@DiBosco said in Help using an hello world DLL (that might be at fault):
if you're releasing a DLL out into the wild, surely you don't need a different one for each compiler that is being used? I thought you were providing a binary that any development enviroment in any language could use?
Yes and No :) Again, my knowledge for Windows may not be perfect :) I believe you will find you have only been able to successfully "cross-link" between MSVC & MinGW because the content of your DLL is pure C? If/when you try to make the DLL content be C++ I believe the link will fail. Depends whether you are intending to do that! You could make your DLL be C++ now, temporarily, and verify if I am correct! Then you will know going forward.
It may be that a Windows Qt-er chimes in here to give you more clarity, I think I have said what I think I know ;-)
That is a very good question/point. As things stand, yes the dll just has C functions in it. The tutorial I based this on did set the project up as C++, but said tutorial instructs you to put:
extern "C" CTR6500_API
In front of each of your functions in the header file.
I had just assumed C and C++ were interchangeable here but it does look like C, not C++ in the source files.
@DiBosco
I do not know whether to count as "C++" it depends on (a) flags you pass to compiler or (b) content is C++ or maybe even file extension. What I believe I do know is if it is C++, by whatever reckoning, you cannot mix MinGW C++ code/modules/objects/libs with MSVC. So if you continue this way one side or the other of your MSVC/MinGW will have to be limited to C in order to link them. Which might suffice for some purpose of yours, but not if they are each proper C++ projects. And you won't be able to mix them if they both want to call any Qt stuff.A lot of basic libraries supplied with Windows are C only. Although not sure, I think this may apply to the whole of Windows, certainly the "Windows SDK" stuff. That can be used. As can, importantly, the runtime libraries named something like
MSVCRT.DLL/LIBwhich give basic start up, memory management and that sort of thing. MinGW does use these from MS/MSVC, I believe. Because they are all C only.As for whether things provide only one compiled version, as you suggested, or multiple compiled versions. Well, like I say I cannot check, but I assume that Qt itself, if you fetch pre-compiled for Windows (as I believe you can), will supply a completely separate set of its Qt/C++ DLLs in a download for MinGW versus for MSVC? So they are supplied differently, if I am correct.
I would have thought you should pick one of MinGW or MSVC, and one of Creator or VS, and stick to that for all your work.
-
@JonB Many thanks for all the help. It's made me go off and do a pile of reading and I understand a little more. I had never understood, for example, what the extern "C" meant, but I think I do now. Some of the reading has suggested to me that Linux has all this sussed a lot better than Windows (but that woud be no surprise ;-) )
This post:
https://forum.qt.io/topic/75458/compatibility-libraries-generated-by-msvc-and-mingw/3
Suggests that as long as I follow a few rules I should be OK.
I am guessing that you can use internal functions using C++ classes as long as anything exposed to the outside world is C style.
I'm still a bit comfused because I am following a PDF for this specific project that talks about what functions must be supplied for the DLL and it gives an example of how to do these functions in Pascal! So my original assumption was any language could be used for the DLL and any language could then use that DLL. From what I can tell, the document I'm following was written in October 2013 so it's a fair while ago, if not from the really early days of Windows - already up to Win 8 by then.
It is the case, I think that at least one of the companies who'd want to use this DLL still use Delphi!