I just created a project in Unreal 4 with C++ (Visual Studio 2019).
As soon as I build the project with only a basic movement class, Visual Studio shows these errors (see the image).
Unresolved External Symbol error
I installed Visual studio following the official guide: https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/DevelopmentSetup/VisualStudioSetup/
This is the code in the cpp file:
// Fill out your copyright notice in the Description page of Project Settings.
#include "MiJugador.h"
// Sets default values
AMiJugador::AMiJugador()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AMiJugador::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AMiJugador::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void AMiJugador::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
check(PlayerInputComponent);
PlayerInputComponent->BindAxis("Forward", this, &AMiJugador::MoveForward);
PlayerInputComponent->BindAxis("Right", this, &AMiJugador::MoveRight);
}
void AMiJugador::MoveForward(float amount)
{
if (Controller && amount)
{
FVector fwd = GetActorForwardVector();
AddMovementInput(fwd, amount);
}
}
void AMiJugador::MoveRight(float amount)
{
if (Controller && amount)
{
FVector right = GetActorRightVector();
AddMovementInput(right , amount);
}
}
And this is the header file:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MiJugador.generated.h"
UCLASS()
class CPPPRACTICE_API AMiJugador : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AMiJugador();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// Funciones para movimiento
void MoveForward(float amount);
void MoveRight(float amount);
};
Most of the code is automatically done by Unreal. Anyone can help me get rid of these error? Thi is geting me crazy, I've tried many things as including .lib in project settings but none of those helped me...
Thank you in advance for your time.
You are missing (or your linker can't find) an OpenGL library.
Most likely, you are including .lib in project settings wrong.
Related
I have an issue I don't understand. My project is quite simple for now. I have a shared library Engine which is called by my executable. I'm trying to move the entry point inside my shared library, so the executable part only has functions and some class to create.
---EDIT: I edit to post the project as it is reproductible easily.
To do so, I have these files in my shared library:
entry.h
BaseGame.h
Application.cpp
Here is entry.h
#include "BaseGame.h"
extern game* create_game();
int main(int argc, char *argv[])
{
auto testgame = create_game();
delete testgame;
return 0;
}
BaseGame.h
class __declspec(dllexport) game
{
public:
game() = default;
virtual ~game();
virtual bool initialize() =0;
virtual bool update(float deltaTime) =0;
virtual bool render(float deltaTime) =0;
virtual void on_resize() =0;
};
Application.cpp
#include "BaseGame.h"
class __declspec(dllexport) Application
{
public:
Application()=default;
~Application()=default;
};
And in my executable, I have two files entry.cpp which defines create_game and my_game.h which inherited from game.
entry.cpp
#include <entry.h>
#include "my_game.h"
game* create_game()
{
return new myGame;
}
and my_game.h:
class myGame : public game
{
public:
myGame(){};
~myGame() override = default;
bool initialize() override;
bool update(float deltaTime) override;
bool render(float deltaTime) override;
void on_resize() override;
};
my_game.cpp:
#include "my_game.h"
bool myGame::initialize()
{
return true;
}
bool myGame::update(float deltaTime)
{
return true;
}
bool myGame::render(float deltaTime)
{
return true;
}
void myGame::on_resize()
{
}
What I don't understand is that I always get an linker error when building my exe:
Création de la bibliothèque ..\bin\testbed.lib et de l'objet ..\bin\testbed.exp
entry-3b33f2.o : error LNK2019: symbole externe non résolu "public: virtual __cdecl game::~game(void)" (??1game##UEAA#XZ) référencé dans la fonction "public: virtual __cdecl myGame::~myGame(void)" (??1myGame##UEAA#XZ)
..\bin\testbed.exe : fatal error LNK1120: 1 externes non résolus
Also here is how i build my shared library:
SET assembly=Engine
SET compilerFlags=-g -shared -Wvarargs -Wall -Werror
SET includeFlags=-Isrc
SET linkerFlags=-luser32
SET defines=-D_DEBUG_EG -DGEXPORT -D_CRT_SECURE_NO_WARNINGS
ECHO "Building %assembly%%..."
clang++ %cFilenames% %compilerFlags% -o ../bin/%assembly%.dll %defines% %includeFlags% %linkerFlags%
And here is my executable:
SET assembly=testbed
SET compilerFlags=-g
REM -Wall -Werror
SET includeFlags=-Isrc -I../Engine/src/
SET linkerFlags=-L../bin/ -lEngine.lib
SET defines=-D_DEBUG_EG -DGIMPORT
clang++ %cFilenames% %compilerFlags% -o ../bin/%assembly%.exe %defines% %includeFlags% %linkerFlags%
Even if game is exported. Does anyone see something wrong? PS: I'm using Clang as the compiler.
The game class lacks a destructor definition. I suggest making it default:
class myGame : public game
{
public:
myGame(){};
~myGame() override = default; // here
bool initialize() override;
bool update(float deltaTime) override;
bool render(float deltaTime) override;
void on_resize() override;
};
You may also remove the default constructor and destructor from myGame. It'll be default constructible and have a virtual destructor by default.
class myGame : public game
{
public:
// myGame(){}; // remove
// ~myGame() override = default; // remove
// ...
Other notes:
All your header files should have header guards to prevent including the same file twice in one translation unit.
my_game.h should #include "BaseGame.h" to get the definition of game.
You example is not entirely complete. I assume the destructor ~game() is actually defined in some cpp file of the shared library. And my_game.h needs to include BaseGame.h (since myGame derives from game). So basically my_game.cpp in the executable ends up seeing the definition of game as shown, including the __declspec(dllexport). However, the executable should not see __declspec(dllexport) (i.e. the exe should not export game) but rather it should see __declspec(dllimport) (i.e. the exe should import game). So you want to define game with __declspec(dllexport) while building the dll and __declspec(dllimport) while building the executable.
The typical way to conditionally have one or the other is by using a macro and changing its definition based on a preprocessor symbol which is different for the exe and the dll. For example (adapted from the official documentation):
// Either in BaseGame.h or in a dedicated header
// that gets included by BaseGame.h.
#ifdef EXPORT_GAME_SYMBOLS
#define GAME_DECLSPEC __declspec(dllexport)
#else
#define GAME_DECLSPEC __declspec(dllimport)
#endif
// BaseGame.h
class GAME_DECLSPEC game
{ ... class definition ... };
While building the dll, you do define EXPORT_GAME_SYMBOLS in the preprocessor (-DEXPORT_GAME_SYMBOLS). But while building the executable, you do not define EXPORT_GAME_SYMBOLS.
The linker complains only about the destructor of game because only the destructor has a non-inline implementation in your example. The default constructor is inline (game() = default;, meaning that an export is not necessary for the linker to find an implementation) and the other functions are pure (meaning that they do not have an implementation to begin with).
Hence, an alternative here would be to completely remove the export/import stuff from game and define the destructor inline, too (virtual ~game() = default;).
But of course, if everything is inline, you do not need to build a shared library to begin with...
Side notes:
The __declspec(dllexport) on Application makes no sense since it is in a .cpp file of the dll, meaning that code in the executable can never see the definition of Application. (Except if you #include "Application.cpp", which you shouldn't.) So no need to export the symbol.
As others have noted, having the main() in the header file is uncommon. You could move it e.g. to my_game.cpp or a dedicated main.cpp in your exe project.
I try to implement the pawn navigation to the player in my game. When I tried that in BP site, it worked perfectly, but I try to transform that in C++ code. And I got a kind of wird error. Befor this I faced another error but I find the NavigationSystem was changed a bit in my ue version, but I figured out problem by changing to UNavigationSystemV1. It might be interfering with my class?
NavPath pointer it gave me the error.
Here is the error list:
> Error (active) E0393 pointer to incomplete class type is not allowed 37
> Error (active) E0393 pointer to incomplete class type is not allowed 40
> Error C2027 use of undefined type 'UNavigationPath'37
> Error C2027 use of undefined type 'UNavigationPath' 40
Here is the part of problematic code:
FVector ASTrackerBot::GetNextPathPoint()
{
ACharacter* PlayerPawn = UGameplayStatics::GetPlayerCharacter(this, 0);
UNavigationPath* NavPath = UNavigationSystemV1::FindPathToActorSynchronously(this,
GetActorLocation(), PlayerPawn);
if (NavPath->PathPoints.Num() > 1)
{
return NavPath->PathPoints[1];
}
return GetActorLocation();
}
Here is my entire private cpp file:
#include "AI/STrackerBot.h"
#include "Components/StaticMeshComponent.h"
#include "GameFramework/Character.h"
#include "Kismet/GameplayStatics.h"
#include "Runtime\NavigationSystem\Public\NavigationSystem.h"
#include "Runtime/Engine/Classes/Components/InputComponent.h"
// Sets default values
ASTrackerBot::ASTrackerBot()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComp"));
MeshComp->SetCanEverAffectNavigation(false);
RootComponent = MeshComp;
}
// Called when the game starts or when spawned
void ASTrackerBot::BeginPlay()
{
Super::BeginPlay();
}
FVector ASTrackerBot::GetNextPathPoint()
{
// parcurgere drum pana la locatia playerului
ACharacter* PlayerPawn = UGameplayStatics::GetPlayerCharacter(this, 0);
UNavigationPath* NavPath = UNavigationSystemV1::FindPathToActorSynchronously(this, GetActorLocation(), PlayerPawn);
if (NavPath->PathPoints.Num() > 1)
{
// Return next point in the path
return NavPath->PathPoints[1];
}
// nu a reusti sa gaseasca drumul
return GetActorLocation();
}
// Called every frame
void ASTrackerBot::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
And here is my header file:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "STrackerBot.generated.h"
UCLASS()
class GAME_API ASTrackerBot : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ASTrackerBot();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
UPROPERTY(VisibleAnywhere, Category = "Components")
UStaticMeshComponent* MeshComp;
FVector GetNextPathPoint();
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
You may also need to add the NavigationSystem module to your Project.Build.cs file in the PublicDependencyModuleNames array.
The definition of UNavigationPath needs to be available at the point where you do NavPath->PathPoints. Without the definition, how does the compiler know that UNavigationPath even has a member called PathPoints? You can have a pointer to a declared but undefined class (i.e., one you defined like class UNavigationPath; with no body) and pass it around but you can't access any of its members. Find the header file that defines UNavigationPath and make sure it's included in your source.
Some background information first.
I'm currently trying to write a c++ class that can parse a file and generate a tree structure from it that I will be able to use for Inverse Kinematics. To do this I'm making use of some ROS libraries that are able to incorporate the functionality that I need, namely urdf and kdl.
I've managed to link the libraries into the build system through following the instructions here https://wiki.unrealengine.com/Linking_Static_Libraries_Using_The_Build_System
My class can now recognize the structures that I want to make use of, and compiles successfully, but unfortunately Unreal crashes when I try to stop it running,
The code below is from my c++ file, and the issue seems to revolve around garbage collection of my urdf model, as it manages to successfully parse the file only to crash on stopping.
#include "AIKTester.h"
#include "Runtime/Core/Public/Misc/Paths.h"
#include "Runtime/Core/Public/HAL/FileManager.h"
#include <string>
// Sets default values
AAIKTester::AAIKTester()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AAIKTester::BeginPlay()
{
Super::BeginPlay();
urdfParser();
}
// Called every frame
void AAIKTester::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
bool AAIKTester::urdfParser()
{
// Grab relative project path for file system and convert to string
FString RelativeProjPath = FPaths::ProjectDir();
std::string ProjPath(TCHAR_TO_UTF8(*RelativeProjPath));
// Try parse urdf file into model using relative project path and urdf file location
if (!my_model.initFile(ProjPath + "Source/Project/robot.urdf")) {
UE_LOG(LogTemp, Log, TEXT("Failed to parse urdf file"));
return false;
}
else {
UE_LOG(LogTemp, Log, TEXT("Parsed the urdf file"));
return true;
}
}
And here is the included header file:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "../../ThirdParty/ROS2/Includes/urdf/model.h"
#include "../../ThirdParty/ROS2/Includes/kdl/tree.hpp"
#include "../../ThirdParty/ROS2/Includes/kdl_parser/kdl_parser.hpp"
#include "AIKTester.generated.h"
UCLASS()
class PROJECT_API AAIKTester : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AAIKTester();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
urdf::Model my_model;
bool urdfParser();
};
I've tried to get my head around the call stack, but unfortunately I can't get any clarity about how to solve this problem. The error code and call stack seem to change every other time running it, most recently displaying:
Exception thrown at 0x00007FF80FEE731E (nvwgf2umx.dll) in UE4Editor.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Any help would be greatly appreciated, thanks.
I've successfully built SFML from github with static linkage for libraries and against runtime (the one downloaded from website is dynamically linked against runtime, which requires users to have msvcrXXX.dll installed when used with Visual Studio). It works fine and all, until I start using my code.
The problem is sf::RenderWindow::draw, when called with something like sf::RectangleShape it works no problem and displays nice colored rectangle. However, when I start using my own class for this, it pops an error.
The class hierarchy:
There is a base class as follows:
class ButtonBase : public sf::Drawable{
public:
virtual ~ButtonBase() {}
virtual void callback(ButtonClickState) = 0;
virtual void onHover(HoverState) = 0;
virtual void draw(sf::RenderTarget&, sf::RenderStates) const = 0;
virtual sf::Sprite& getBackground() const = 0;
virtual LabelBase& getLabel() const = 0;
virtual TooltipBase& getTooltip() const = 0;
virtual void hide() = 0;
virtual void show() = 0;
virtual bool isHidden() const = 0;
virtual int getZ() const = 0;
virtual void setZ(int) = 0;
};
As you can see, this class inherits sf::Drawable so all Buttons that inherit ButtonBase can be used in a way: window.draw(buttonInstance);.
The Button looks roughly as this:
class Button final : public ButtonBase{
mutable Label label;
sf::Texture texture;
mutable sf::Sprite buttonImage;
mutable int z;
bool active;
public:
//constructors, destructors, whatnot
void draw(sf::RenderTarget& target, sf::RenderStates states) const
{
if (active)
{
target.draw(buttonImage, states);
target.draw(label, states);
//target.draw(bTltp, states);
}
}
//more stuff
};
Most stuff is irrelevant. I boiled the problem down to when I call the draw inside Button after the function returns/goes out of scope, this error is popped:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
I am using the default one: cdecl convention. Is SFML build with SFML_LINK_STD_STATICALLY (or whatever is that flag in CMake called) to true using some weird/other convention?
To note, I have defined SFML_STATIC flag in preprocessor macros, and I am using correct (debug with debug, normal with release build) libs.
I am very sure that this code will work with dynamically linked library downloaded from the official website, because I have made whole project which fully worked.
I'm trying to get Box2D running with my Cocos2d-x project. I'm adding collision detection but I get a linker error
Undefined symbols for architecture i386: "CContactListener::CContactListener()", referenced from: HelloWorld::init() in HelloWorldScene.o
I've tried several things and researched for a few days but can't figure it out. Any help wold be great.
Here's some code pieces
HelloWorldScene.h
CContactListener *_contactListener; //Variable declared and #include "ContactListener.h" is present at the top
HelloWorldScene.cpp
_contactListener = new CContactListener(); //This line gets the error
_world->SetContactListener(_contactListener);
ContactListener.h
class CContactListener : public b2ContactListener {
public:
CContactListener();
~CContactListener();
std::vector<ContactData>_contacts;
virtual void BeginContact(b2Contact* contact);
virtual void EndContact(b2Contact* contact);
virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
};
ContactListener.cpp
#include "ContactListener.h"
CContactListener::CContactListener(): _contacts()
{
}
CContactListener::~CContactListener()
{
}
//...other functions
CContactListener.cpp was not added the the target build in Xcode. I simply checked the target box for my project in the File Inspector for the .ccp file. Easy fix.