1

One more day, one more dumb question on stackoverflow, please excuse me. The idea was to make dll and then import it to another project to use it there, but after including dll header file in second project and writing paths to the .lib and header files I still have these errors:

E0070   incomplete type is not allowed  prjct-1 D:\projects-vs\firstTryWT\prjct-1\prjct-1.cpp   33
C2027   use of undefined type 'stmr::MathProblem'   prjct-1 D:\projects-vs\firstTryWT\prjct-1\prjct-1.cpp   33
C2079   'problem' uses undefined class 'stmr::MathProblem'  prjct-1 D:\projects-vs\firstTryWT\prjct-1\prjct-1.cpp   33  
C3493   'problem' cannot be implicitly captured because no default capture mode has been specified  prjct-1 D:\projects-vs\firstTryWT\prjct-1\prjct-1.cpp   35  

I've tried to rebuild, change some code till I understand that I either already did what is needed or I don't know what is needed. Anyway, here is the code:

Dll header file:

#pragma once

#ifdef STMR_EXPORTS
#define STMR_API __declspec(dllexport)
#else
#define STMR_API __declspec(dllimport)
#endif

#include <vector>
#include <string>

namespace stmr
{
    class STMR_API MathProblem;
    class STMR_API Operation;
}

Definitions of both classes have STMR_API keyword. I have 'STMR_EXPORTS' in C/C++ -> Preprocessor and '$(OutDir)$(TargetName).lib' in Linker -> Advanced -> Import Library so that I have the import lib generated.

main cpp of the project which is supposed to use the dll:

#include <Wt/WApplication.h>
#include <Wt/WBreak.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
#include <Wt/WPushButton.h>
#include <Wt/WText.h>

#include "stmrLib.h"


class HelloApplication : public Wt::WApplication
{
public:
    HelloApplication(const Wt::WEnvironment& env);

private:
    Wt::WPushButton* button_m;
    Wt::WText* summary_m;
};

HelloApplication::HelloApplication(const Wt::WEnvironment& env)
    : Wt::WApplication(env)
{
    button_m = root()->addWidget(std::make_unique<Wt::WPushButton>());
    summary_m = root()->addWidget(std::make_unique<Wt::WText>()); 
    stmr::MathProblem problem = stmr::MathProblem(problemText_m->text().narrow());
    auto solving = [this] {   
        summary_m->setText("This equals " + std::to_string(problem.solve()));
    };
    button_m->clicked().connect(solving);
}

int main(int argc, char** argv)
{
    return Wt::WRun(argc, argv, [](const Wt::WEnvironment& env) {
        return std::make_unique<HelloApplication>(env);
        });
}

I have correct path to the .lib file for dll in Linker -> General -> Additional Library Dependencies and stmr.lib/stmrd.lib in Linker -> Input -> Additional Dependencies for Release/Debug Not sure if the problem in exporting or importing of the dll.

Feedback about question quality is appreciated.

4
  • 1
    Whether it's a DLL, or any other kind of library, is irrelevant - the header only provides a forward declaration of stmr::MathProblem, so you can't create instances of it. You need to include the class definitions. Commented Aug 13, 2021 at 11:41
  • 1
    @molbdnilo you are right. I also tend to use the pimpl pattern for classes I export. This tends to keep all kinds of implementation details and extra header files out of the publicly visible header file. en.cppreference.com/w/cpp/language/pimpl Commented Aug 13, 2021 at 11:56
  • @molbdnilo i need to include it into what? They are in the cpp and header files of the dll. And if i need to include them into second project, i don't know how and what will be the matter of the dll then? thanks for your time Commented Aug 13, 2021 at 12:06
  • 2
    You need the class definitions in the headers you include from the main program. The only header you've shown, which is apparently the only one you include, only declares the classes. The definitions are not somehow extracted from the library. Commented Aug 13, 2021 at 12:16

1 Answer 1

4

In C++ (prior to modules) the header file needs to expose enough information about a class for another cpp file to create the object or use the type.

You have just forward declared it, which is enough to make pointers or references to the type and nothing else.

These errors have nothing to do with linking or DLLs or exports.

All compilation units that need to make instances or otherwise call methods of your types need to see the class definition. Put it in the headerfile. Method definitions can be in cpp files and exported.

The pImpl pattern may help you hide details, if you do not want to expose them.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.