0

I've tried to find a solution to this problem by looking through the old questions and answers, but I can't spot what's wrong in my case. I get the following error:

Error 66 error LNK2019: unresolved external symbol "public: static class PhysicsBody *
__cdecl PhysicsBody::createBox(float,float,enum PhysicsBodyType,float)"
(?createBox@PhysicsBody@@SAPAV1@MMW4PhysicsBodyType@@M@Z) referenced in function
"public: __thiscall Enemy::Enemy(void)" (??0Enemy@@QAE@XZ)

The weird thing is, the code file is there, both .H and .CPP, and they are included in the solution and compiled correctly. Here's the code files:

// Enemy.h
#pragma once

class Enemy {
public:
    Enemy();
private:
    PhysicsBody* m_body;
};

// Enemy.cpp
#include "Enemy.h"
#include "PhysicsBody.h"

Enemy::Enemy() {
    m_body = PhysicsBody::createBox(1.f, 1.f, PhysicsBodyType::Dynamic);
}

// PhysicsBody.h
#pragma once

enum PhysicsBodyType {
    Static, Dynamic, Kinematic
};

class PhysicsBody {
public:
    static PhysicsBody* createBox(float width, float height, PhysicsBodyType type, float mass = 1.f);
private:
    PhysicsBody();
};

// PhysicsBody.cpp
#include "PhysicsBody.h"

PhysicsBody::PhysicsBody() {

}

PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
    return new PhysicsBody();
}

(I have cropped out some non-relevant code here.)

I've literally skimmed through the code tens of times and cannot spot anything wrong with it. I have similar code throughout my project and everything else works. For some reason, this PhysicsBody class causes these problems. I've checked that it's included in the project / solution, the file type is C/C++ Code, it's not marked as content and overall it should be working.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
manabreak
  • 5,415
  • 7
  • 39
  • 96
  • Are you on Windows? Do you build a DLL? Are both Enemy and PhysicsBody within the same module? (DLL or exe)? – ds27680 Sep 13 '14 at 18:51
  • I am on Windows, not building a DLL, and both are in the same project. There's about 20 methods in PhysicsBody class, and it gives the error on three of them, the one showed in the code above is just an example of one. – manabreak Sep 14 '14 at 05:14
  • Ok. I see you solved your problem in the meantime. On Windows a tool that I often use to trpoubleshoot such issues is Dependency walker http://www.dependencywalker.com. Often by using it you find that either the class is not exported out of thr Dll it rrsides in (so the linker is rightfully complaining) or that the "mangled" name of the exported function differs from the one in the error message (which might be due to linking to an outdated export library for a DLL). This is why I asked if you are on Windows. – ds27680 Sep 14 '14 at 10:00

2 Answers2

1

The problem was quite probably caused by a faulty VS project file. I copied the contents of PhysicsBody.h / .cpp files, deleted both files, created new files and pasted the original contents. All code is exactly the same and it works now, so I conclude that it's a VS-related bug.

manabreak
  • 5,415
  • 7
  • 39
  • 96
0

Bug in the code in the question

The function that is not found is:

PhysicsBody::createBox(float, float, enum PhysicsBodyType, float)

The function that is shown as defined is:

PhysicsBody::createBox(float, float, enum PhysicsBodyType)

There's a different number of arguments between the two functions.

Questions arising:

  1. Which is the correct definition?
  2. How did the erroneous definition get used?
  3. Where was the declaration for the erroneous use?

You may need to simply recompile everything. You may need to look at where your PhysicsBody class is defined because it is defined in two places.

This problem has now been fixed in the question.


No significant bug in the code in the question

With the code as in the amended question (with #include "PhysicsBody.h" added at the start of Enemy.h so the header can be compiled standalone), and ignoring warnings about the unused parameters to the createBox function, I can compile and link the code using g++ from GCC 4.9.1 and a trivial main():

#include "Enemy.h"

int main()
{
    Enemy e;
    return 0;
}

That suggests to me that the problem is not in the code you show but rather the problem is in the code you don't show. Please study how to create a MCVE (How to create a Minimal, Complete, and Verifiable Example?) or SSCCE (Short, Self-Contained, Correct Example) — two names and links for the same basic idea.

Please post exactly the minimal code that reproduces the problem. (I created a new subdirectory, placed 5 source files — two headers, two implementation files and a trivial main() — into the directory, and a makefile and compiled from there. I suggest you do the equivalent on your Windows machine.)

If you affirm that the code posted above plus the main.cpp I show does (1) compile and (2) fail to link, thus reproducing the problem, then there is superficially a bug in MSVC. I think that's unlikely to be the case, but funnier things have been known.

For the record, I was compiling on Mac OS X 10.9.4 Mavericks with GCC 4.9.1 and the following commands (with warning messages shown):

$ g++ -O3 -g  -std=c++11 -Wall -Wextra    -c Enemy.cpp
$ g++ -O3 -g  -std=c++11 -Wall -Wextra    -c PhysicsBody.cpp
PhysicsBody.cpp:8:43: warning: unused parameter ‘width’ [-Wunused-parameter]
 PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
                                           ^
PhysicsBody.cpp:8:56: warning: unused parameter ‘height’ [-Wunused-parameter]
 PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
                                                        ^
PhysicsBody.cpp:8:80: warning: unused parameter ‘type’ [-Wunused-parameter]
 PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
                                                                                ^
PhysicsBody.cpp:8:92: warning: unused parameter ‘mass’ [-Wunused-parameter]
 PhysicsBody* PhysicsBody::createBox(float width, float height, PhysicsBodyType type, float mass) {
                                                                                            ^
$ g++ -O3 -g  -std=c++11 -Wall -Wextra    -c main.cpp
$ g++ -o main *.o
$ ./main
$ echo $?
0
$
Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Ah, that missing float is a typo in my code example, I accidentally copy-pasted the wrong overload of the function. The problem isn't there. I've tried recompiling the code, cleaning the solution, rebuilding... nothing seems to help. – manabreak Sep 13 '14 at 17:32