简体   繁体   中英

Linker error when function definition is in cpp file

My solution has three projects: GoogleTest (for using Google Test), Vi (for the bulk of the logic) and ViTests (for the unit tests using Vi). The ViTests project references the Vi project and the Google Test project.

Vi has the following code in v1.h

#pragma once

namespace Vi
{
    class Vi1
    {
    public:
        int SomeInt();
    };
}

And the matching v1.cpp

#include "vi1.h"

namespace Vi
{
    int Vi1::SomeInt()
    {
        return 123;
    }
}

The test function in ViTests follows

TEST(Vi1Foo, SomeIntIsSame)
{
    Vi1 v = Vi1{};
    EXPECT_EQ(123, v.SomeInt());
}

The linker error says there's an unresolved symbol SomeInt . However, I can make the linker error go away by inlining the function like so:

namespace Vi
{
    class Vi1
    {
    public:
        int SomeInt() { return 123; }
    };
}

Why is the unit test project not finding the SomeInt function definition when it's placed in a separate cpp file?

Thanks.

Extra details incase useful: I'm using Visual Studio 2015.

The error message:

Error   LNK2019 unresolved external symbol "public: int __thiscall Vi::Vi1::SomeInt(void)" (?SomeInt@Vi1@Vi@@QAEHXZ) referenced in function "private: virtual void __thiscall ViTests::Vi1Foo_SomeIntIsSame_Test::TestBody(void)" (?TestBody@Vi1Foo_SomeIntIsSame_Test@ViTests@@EAEXXZ) Vi_Tests    C:\Users\MyName\Vi\Vi_Tests\Vi_Tests.obj    1

Project types: Vi is Win32 Application, ViTests is Win32 Console Application, GoogleTest is a static library.

I was working under a silly false assumption. I was assuming that VS would just pickup the cpp files because I was referencing the project containing them and including the correct header files but this isn't the case.

nabijaczleweli said I should link "towards the file with the function definition". After a bit of exploring online I found out how to do this. I found this post outlining a solution. The cpp files themselves must be added to the test project. This was done by right-clicking on ViTests, selecting "Add Existing Files" and selecting vi1.cpp.

This worked but I was quite unhappy with this solution because I had to add these files as I needed them. I found I could get around this changing the type of project Vi was to a static library. This is described here . Michael Burr's comment describes a way of linking to the object files that would also work.

I wouldn't have figured this out so quickly without the help of the posters in this thread. Thank you very much people.

You didn't specify what is the type of the projects. I'm guessing they are DLLs, and as such non-inlined functions or classes you wish to use outside them need to exported: either declared as __declspec(dllexport) at the source or listed at a DEF file.

If you go with __declspec(dllexport), remember to __declspec(dllimport) the functions at the consuming project. This is typically achieved with a macro used as a qualifier at the .h file, which resolved differently on different projects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM