2

I created a C++ project in Visual Studio 2019. I added two files to it: MyClass.hpp and MyClass.cpp. Then I created a test project and added the original project as a reference.

If I doubleclick on the reference in the test project, I can see MyClass. But if I try to run the tests, I get this error:

MyTest.obj : error LNK2019: unresolved external symbol "public: struct MyRef __thiscall MyClass::SetData(struct Data)" (?SetData@MyClass@@QAE?AUMyRef@@UData@@@Z) referenced in function "private: virtual void __thiscall MyTest_SetData_Test::TestBody(void)" (?TestBody@MyTest_SetData_Test@@EAEXXZ)

What do I wrong? Why is MyClass.cpp not compiled, even if it is in the referenced project? I can build the original project without error. I only get the link error, when I try to build the test project.


I came across this question about unresolved external symbol error, but it did not solve my issue. This is a Visual Studio specific problem.

If I add MyClass.cpp to the test project manually, then it works. But I do not want to do that for each file, because my project may have many more cpp source files, not just this one. I would like to make it work using the "references" feature.

When I created the test project, I selected the original project as a reference.

Iter Ator
  • 8,226
  • 20
  • 73
  • 164
  • Do you have an implementation for 'MyTest_SetData_Test::TestBody(void)' in your 'MyClass.cpp' – MH Alikhani Apr 12 '20 at 18:10
  • @MHAlikhani Yes, I do have an implementation – Iter Ator Apr 12 '20 at 18:23
  • @1201ProgramAlarm Please reopen this question. The linked question did not solve the issue. – Iter Ator Apr 12 '20 at 18:28
  • 1
    How did you add the project reference? Is is a "shared project" reference? – 1201ProgramAlarm Apr 12 '20 at 18:37
  • @1201ProgramAlarm I just simply selected the original project as a reference, when I created the test project. What is the difference between shared and simple references? The original project is not listed under "shared projects", and I can't find out, how to make an existing project shared. – Iter Ator Apr 12 '20 at 18:58
  • 2
    Project references are usually used for .NET assemblies and related things, and not very often with native code. This older [question](https://stackoverflow.com/questions/8115974/what-are-visual-studio-project-references) may shed some light. A [shared project](https://learn.microsoft.com/en-us/visualstudio/ide/managing-references-in-a-project?view=vs-2019#shared-project-references) will compile into each project that references it. Or you can go the traditional DLL route. – 1201ProgramAlarm Apr 12 '20 at 19:24
  • Maybe related:https://stackoverflow.com/questions/47515089/lnk2019-unresolved-external-symbol-in-vs-unit-testing and https://stackoverflow.com/questions/36811378/cppunittest-link-to-windows-application – rene Apr 12 '20 at 19:27
  • 1
    @IterAtor if the original project MyClass is dynamic library, then add in your test project properties ->Linker->input : MyClass.lib and in Linker->general->Additional Library directories the path to your lib – Jaziri Rami Apr 23 '20 at 09:58
  • also see https://stackoverflow.com/questions/15579172/undefined-reference-to-class-constructor-including-cpp-file-fixes – OMGtechy Apr 27 '20 at 11:36

2 Answers2

5

Adding project B to project A as a reference basically just assures that project B is compiled whenever project A is compiled.

You need extra setup:

  1. make sure project B builds as a library (and not an executable)
  2. consider two paths accessible from both projects. This will be where the project B library will be installed. This comprises of two things:
    • the binary (static library is the simplest setup)
    • the library headers
  3. on compilation of project B you need to install both the resulting binary and the headers to these paths. For this you can make a post build step that copies the necessary files: Properties » Build Events » Post-Build Event

    Alternately just use project B's build folder and source location.

  4. in project A:

    • add the header path to the include paths:
      Properties » C/C++ » General » Additional include directories
    • add the library to the list of libraries to link:
      Properties » Linker » Input » Additional dependencies
    • add the binary path to the linker library search
      Properties » Linker » General » Additional Library Directories
bolov
  • 72,283
  • 15
  • 145
  • 224
1

Just to add something to the previous comments/answers:

You didn't mention if you build your reference project as a static or dynamic library.

This can be set by going to the project's Properties->General->Configuration Type

Note that if you select Dynamic Library (.dll), your symbols (such as MyClass::SetData(struct Data)) will not be exported by default and you'd need to add the __declspec(dllexport) keyword. See here

La bla bla
  • 8,558
  • 13
  • 60
  • 109