Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

MVSC created dll crashes in Qt



  • Hello and thank you for your time to help me and thanks for Qt it is a really cool toolkit.

    I am writing my thesis software in Qt and I came across this problem today.

    I want to use objects created from classes defined in dynamic libraries. I created a .dll library with Visual Studio 2019 (default 2019 platform toolkit set).

    The .dll has only really simple test classes. It has an abstract Base class with a pure virtual function test() and a Child class that inherits from the Base and implements the test function printing some text to the stdout. And also there is a function that returns a Child object.

    Tested it in a simple .cpp program (also created with VS2019) to see if I can get a Child object from the dll into a Base* and call the test function defined in the .dll and it worked okey.

    The problem: I tried to do the same thing with the same .dll, in a basic Qt Widget application (Qt 4.11.0, MSVC2015 32bit compiler) that has only a mainwindow and a pushbutton. The dll import works fine, I get back the Child object from the .dll but at the test() function call the program crashes.

    typedef Base* (*FUNCPOINTER)();
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        Base* b;
        FUNCPOINTER myFunction;
    
        QLibrary myLib(dllname);
        myFunction = (FUNCPOINTER) myLib.resolve(procname);
        if (myFunction){
            qDebug("myFunction ok");
            testobj = myFunction(); //gives back a Child object
            if(testobj){
                testobj->test(); //crash
                delete testobj;
             }
        }
        else
            qDebug("myFunction is not ok");
    }
    

    I started debugging and saw that at the virtual function call it just loses it.

    My questions:

    1. I could not understand what is happening unfortunatley I do not have much more time to figure it out I spent the day looking after solution but no idea. If it works in a Visual Studio project but not in Qt it has to do something with the compiler difference I suppose. So simply MVSC2019 created.dll-s will not work with Qt is this true?
    2. I messed up something in the code maybe?
    3. What would be the easiest solution to come around this problem? Shall I just create .dll-s with Qt and use those and that is all?

    Thank you, I am really appreciating your time and help.


  • Moderators

    Hi, welcome to the forum.

    1. VS2015 and 2019 are not binary compatible. If you want to link a dll made with one in the other you would have to, at minimum, stick to C interface (extern "C") and even then wou have a problem with the msvc runtime dlls (you said you use stuff like stdout), so you would have to link your app to both runtimes, which just begs for trouble and won't end well.
    2. That's always a possibility, but if the functions are simple as you say and it works when both the exe and dll are made in VS2019 then I doubt that.
    3. Use the same compiler for entire project. If you already have VS2019 just download Qt for that version and don't mix.

  • Moderators

    @Near-River said in MVSC created dll crashes in Qt:

    (Qt 4.11.0, MSVC2015 32bit compiler)

    I presume you meant Qt 5.11.0. That version has reached end-of-life. If you're starting a new project, I suggest using Qt 5.15.1 for MSVC 2019 32-bit.

    This would also eliminate any compatibility issues that @Chris-Kawa mentioned.

    Tested it in a simple .cpp program (also created with VS2019) to see if I can get a Child object from the dll into a Base* and call the test function defined in the .dll and it worked okey.

    I see that you used QLibrary in your Qt code. How did you implement it in your non-Qt code?

    Anyway, instead of resolving the function at runtime, why not do it at link-time? Simply add the library to your project (see https://doc.qt.io/qtcreator/creator-project-qmake-libraries.html ), #include your library's header file and call your function directly.

    @Chris-Kawa said in MVSC created dll crashes in Qt:

    VS2015 and 2019 are not binary compatible.

    VS2015, 2017, and 2019 are (supposed to be) binary compatible: https://devblogs.microsoft.com/cppblog/cpp-binary-compatibility-and-pain-free-upgrades-to-visual-studio-2019/#binarycompat


  • Moderators

    @JKSH said:

    VS2015, 2017, and 2019 are (supposed to be) binary compatible:

    Yup, my mistake. I forgot if it was VS2015 or VS2017 that started it.



  • @JKSH Hello, thank you for the reply.

    I already have my project 3/4 done in the actual version (Qt 4.11.0). Is it possible for me just to download the 5.11.0 and open the project file and continue the work? I did not used any version specific thing that should be delegated in the newer version I guess (only used Table view, Abstract Table model, buttons etc).

    I see that you used QLibrary in your Qt code. How did you implement it in your non-Qt code?

    In the Visual studio .dll it I implemented it like this:

    #ifdef __cplusplus 
    extern "C" {          
    #endif
    __declspec(dllexport) Base* testfunction() {
        return new Child();
    #ifdef __cplusplus
    }
    #endif
    

    The classes are defined in header files and are included and I did not exported them but I have the same headers included in my Qt project. I read that it is not necessary to import the classes too.

    Anyway, instead of resolving the function at runtime, why not do it at link-time? Simply add the library to your project (see https://doc.qt.io/qtcreator/creator-project-qmake-libraries.html ), #include your library's header file and call your function directly.

    One of the core functions of my project is that the User should be able to import his own pathfinding algorithm at runtime that is written in C++ and it is the member function of the Child class and I will run that search in a grid visualizing the search between a start and a target node ( in the table view will visualize it that I mentioned before). I saw that this is the way to implement it in Qt using QLibrary.

    I do not want to make big changes now like moving to newer version if it takes like rewriting some parts of the project because the deadline is in 13 days so I stay at this version for now I think.

    Solution found:
    I am happy to say that it works now as I used Qt Creator to make the .dll file, so the problem was the compiler difference that is confirmed.

    Thank you so much for your suggestions and help, if you have any further recommendations I appreciate them aswell.


  • Moderators

    @Near-River said in MVSC created dll crashes in Qt:

    In the Visual studio .dll it I implemented it like this:

    #ifdef __cplusplus 
    extern "C" {          
    #endif
    __declspec(dllexport) Base* testfunction() {
        return new Child();
    #ifdef __cplusplus
    }
    #endif
    

    You can use this in Qt too. Qt is a C++ library, so you can use any C++ code in Qt.

    I do not want to make big changes now like moving to newer version if it takes like rewriting some parts of the project because the deadline is in 13 days so I stay at this version for now I think.

    OK, that makes sense. Good luck with your project.

    Solution found:
    I am happy to say that it works now as I used Qt Creator to make the .dll file, so the problem was the compiler difference that is confirmed.

    Thank you so much for your suggestions and help, if you have any further recommendations I appreciate them aswell.

    Great!

    I already have my project 3/4 done in the actual version (Qt 4.11.0).

    Qt 4.11 does not exist. The last version of Qt 4 was Qt 4.8.

    I think you meant Qt Creator 4.11. Note:

    • Qt Creator is an IDE (Integrated Development Environment). You use it to manage and build C++ projects
    • Qt is a C++ library.

Log in to reply