Unreal Engine access violation crashes using third party library code - c++

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.

Related

Unreal 4: Unresolved external symbols

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.

TSubclassOf<> isn't storing the class type

I'm trying to create a laser beam actor that spawns when the player presses the "Fire" action mapping. I can't get TSubclassOf<> to work so that I can spawn the actor that creates the laser. I can declare the variable and compile the project, but I can't seem to use the template anywhere else in the project because the variable isn't initialized??? I'll include my code to help explain what's happening.
Here is my LaserTagCharacter.h file. I've declared the LaserClass variable and I can compile this code with no problems.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "LaserTagCharacter.generated.h"
UCLASS()
class LASERTAG_API ALaserTagCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values
ALaserTagCharacter();
UPROPERTY()
TSubclassOf<class ALaserTagLaser> LaserClass;
protected:
// Called when player fires a laser beam
void OnFire();
};
Moving over to the LaserTagCharacter.cpp file, I've included some debug code and my main objective with creating the template class. I created the template class to use it in a SpawnActor function that will spawn an instance of LaserTagLaser.
#include "LaserTagCharacter.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "LaserTagLaser.h"
#include "Engine/World.h"
// Sets default values
ALaserTagCharacter::ALaserTagCharacter()
{
}
// Called when player uses fire action binding
void ALaserTagCharacter::OnFire()
{
UWorld* World = GetWorld();
FVector SpawnLocation = GetActorLocation();
FRotator SpawnRotation = GetControlRotation();
if (LaserClass)
{
UE_LOG(LogTemp, Warning, TEXT("Yes"))
}
else
{
UE_LOG(LogTemp, Warning, TEXT("No"))
}
World->SpawnActor<ALaserTagLaser>(LaserClass, SpawnLocation, SpawnRotation);
}
The 2 messages I get from the output log when I compile, play, and press the "Fire" action mapping are:
LogTemp: Warning: No
and...
LogSpawn: Warning: SpawnActor failed because no class was specified
If you have any insight on how I can fix this and get TSubclassOf<> to work properly, that would be awesome!
Your code seems ok, but you should add in the header file a specifier inside UPROPERTY, and maybe a Category just give it a title
UPROPERTY(EditDefaultsOnly, Category = "Setup")
TSubclassOf<class ALaserTagLaser> LaserClass;
above the TSubclassOf so that UPROPERTY will be editable in the blueprint editor inside unreal as a drop-menu. Then you must a create a new blueprint based on the ALaserTagLaser. After that, open the drop-menu and you will see only classes and childs of classes of the ALaserTagLaser. Select the blueprint you created, click the compile button inside the blueprintEditor, and then it should be working...

Creating a cross platform c++ touch manager. Passing Objective-c objects in c++ involved code

So I am trying to create a multitouch class that can be used cross platform (iOS, Android, etc). The goal is that the engine does not need to know the platform in order to get updated touch data.
Right now I am doing the general design and am specifically implementing the iOS side. The Android etc side will come much later.
In order to do this I am trying to use the delegation pattern. There are really only two interface items.
There is a method update(float dt) to be called on each new frame with the dt. This method then will return a c++ struct of information about all the touches or perhaps set a property that can be accessed. I am not sure.
On the iOS side the only other function that needs to be called from outside is touchesDown which passes in a NSSet* of the UITouches and the UIView that they are in.
Here is the design I am working with thus far
Multitouch\
PlatformTouchManager.h (C++ Abstract Class with Update)
iOS\
iOSMultiTouch.cpp (Objective-c++)
iOSMultiTouch.hpp (Objective-c++ Class inheriting PlatformTouchManager)
MultTouch.cpp (C++)
MultiTouch.h (C++ class)
Here is PlatformTouchManager.h
#define MAX_TOUCHES 5
#define PLATFORM_iOS
//#define PLATFORM_ANDROID
class PlatformTouchManager {
public:
// Update All The Events
virtual void update(float time) = 0;
};
And of course Multitouch.h
class Multitouch {
private:
PlatformTouchManager* manager;
public:
Multitouch() {
#ifdef PLATFORM_iOS
manager = new iOSMultiTouch();
#endif
}
~Multitouch() {
delete manager;
}
Multitouch(const Multitouch&) = delete;
void update(float dt);
void* getManager() {
return manager;
}
};
And finally iOSMultiTouch.hpp
#include <stdio.h>
#include "../PlatformTouchManager.h"
#include <set>
#import <UIKit/UIKit.h>
class iOSMultiTouch: public PlatformTouchManager {
public:
// Initializer
iOSMultiTouch();
// Destructor
~iOSMultiTouch();
// Update All The Events
void update(float time);
// Touch Down Set
void touchesDown(id<NSSet> set, id<UIView> view);
};
It may be worth noting that this code is included by MultiTouch.h (c++) and my native view code which is objective-c++.
The cross platform engine thus creates a Multitouch object, keeps a reference and every frame calls update.
I am imagining that then iOS UIView will get the Multitouch* from the cross platform engine. Cast it into a iOSMultiTouch* object and call touchesDown:(NSSet *)touches withEvent:(IUView *)view on the delegate.
I am having a serious problem doing this.
If I try to import UIKit inside iOSMUltiTouch.hpp it causes build chaos so it would appear I can only import it inside of the source file. Therefore my touch down method needs to be void touchesDown(void* touches, void* view);.
The problem is then implementing this as when I try to cast these void* pointers into their proper types I get the warning Cast of C pointer type void* to objective-c pointer type id requires a bridged cast.
I understand that there are some ARC concerns here as ARC cannot track such things when casted into a primitive pointer but how do I get around this?
iOSTouchManager does indeed need to hold a strong reference to the UITouch objects up until after the frame the touch is released.
How do I implement this cast? Is there a different way I should be designing my classes to make this easier?
For those of you who were wondering these are the errors that pop up should you import uikit from iOSMultiTouch.hpp
Parse Issue
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:512:1: Expected unqualified-id
../Multitouch/MultiTouch.cpp:9:10: In file included from ../Multitouch/MultiTouch.cpp:9:
../Multitouch/MultiTouch.h:15:10: In file included from ../Multitouch/MultiTouch.h:15:
../Multitouch/iOS/iOSMultiTouch.hpp:15:9: In file included from ../Multitouch/iOS/iOSMultiTouch.hpp:15:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSZone.h:9:1: Expected unqualified-id
../Multitouch/MultiTouch.cpp:9:10: In file included from ../Multitouch/MultiTouch.cpp:9:
../Multitouch/MultiTouch.h:15:10: In file included from ../Multitouch/MultiTouch.h:15:
../Multitouch/iOS/iOSMultiTouch.hpp:15:9: In file included from ../Multitouch/iOS/iOSMultiTouch.hpp:15:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:10:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:10:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSArray.h:5:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSArray.h:5:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObject.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObject.h:8:
Semantic Issues
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:514:9: Unknown type name 'NSString'
../Multitouch/MultiTouch.cpp:9:10: In file included from ../Multitouch/MultiTouch.cpp:9:
../Multitouch/MultiTouch.h:15:10: In file included from ../Multitouch/MultiTouch.h:15:
../Multitouch/iOS/iOSMultiTouch.hpp:15:9: In file included from ../Multitouch/iOS/iOSMultiTouch.hpp:15:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:8:
Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:9: In file included from Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:
Problem
You got ton of errors because you imported iOS framework (UIKit) inside a C++ file (iOSMultiTouch.cpp).
Solution
For implementation files which you need to import iOS frameworks to, you have to use .mm instead of .cpp extension. .cpp is C++ extension, not Objective-C++ extension.
In this case, you need to rename iOSMultiTouch.cpp to iOSMultiTouch.mm. Replace void * with Objective-C pointers and it will work as expected.
Utils.h will keep nothing related to Objective-C and can be used anywhere. Utils.mm is used to work with Objective-C parts.
Utils.h
PlatformTouchManager* GetIOSTouchManager();
Utils.mm
#include "Utils.h"
#include "iOSMultiTouch.hpp"
PlatformTouchManager* GetIOSTouchManager() {
return new iOSMultiTouch();
};
Multitouch.h
#include "Utils.h"
// Other include
class Multitouch {
private:
PlatformTouchManager* manager;
public:
Multitouch() {
#ifdef PLATFORM_iOS
manager = GetIOSTouchManager();
#endif
}
~Multitouch() {
delete manager;
}
Multitouch(const Multitouch&) = delete;
void update(float dt);
PlatformTouchManager* getManager() {
return manager;
}
};

Object accessing the object that contains it in C++

I'm trying to create a game in C++.
It has a "Session" class that kind of manages everything. It contains things like a GraphicsManager, a SoundManager, and the current world. It also contains a static pointer to an instance of itself. This way, I want the world to be available for the GraphicsManager so it can be rendered, for example.
Here is a simplified version of my code:
main.ccp
#pragma once
#include "Session.h"
int main() {
Session::getSession()->run(); //Starts a new session and runs it
return 0;
}
Session.h
#pragma once
#include "GraphicsManager.h"
#include "World.h"
class Session; //Forward declaration so it can have a pointer to itself
class Session {
private:
Session();
static Session* s;
World* w; //Pointer because no world is loaded at the beginning of the program
GraphicsManager gm; //Required right away
public:
~Session();
void run(); //Actually launches the game after preparation; not further declared in this example
World* getWorld(); //Returns the pointer to the current world
static Session* getSession();
}
Session.cpp
#include "Session.h"
Session::Session(): gm(GraphicsManager()) {}
Session* Session::getSession() { //Return an instance of Session. If no instance exist yet, create one.
if(s == NULL) s = new Session();
return s;
}
World* Session::getWorld() {return w;} //Returns a pointer to the current world
GraphicsManager.h
#pragma once;
class GraphicsManager {
private:
void render();
public:
void run(); //Calls the render method repeatedly; no further declaration in this example
}
GraphicsManager.cpp
#include "GraphicsManager.h"
void GraphicsManger::render() {
World* w = Session::getSession()->getWorld(); //Get pointer to current world so it can be rendered
}
The render method is where I'm stuck. If I put #include "Session.h" into the GraphicsManager.h file, it gives me an error because apparently two header files cannot include each other. If I put a forward declaration at the beginning of GraphicsManager.h or GraphicsManager.cpp, Visual Studio tells me that incomplete types are not permitted.
This has been giving me a headache for weeks. I've made games in Java before and there this pattern was accepted. So how can I do this? If this structure is not possible in C++, do you have other suggestions for it?
In GraphicsManager.cpp, the compiler needs to know about the Session, so you have to #include "Session.h" which by the way includes GraphicsManager as well as World.
A forward definition will not be sufficient, as the compiler would not be able to check types of getSession()->getWorld() expression.
Apparently your GraphicsManager.h doesn't rely itself on the other definitions, so there should'nt be an issue here.
Try to include Session.h to GraphicsManager.cpp:
#include "Session.h"
void GraphicsManger::render() {
World* w = Session::getSession()->getWorld(); //Get pointer to current world so it can be rendered
}
This way Session class defenition will be visible for compiler in GraphicsManager.cpp, so it will not generate incomplite type error. On the other hand, Session.h is not included to GraphicsManager header, so there will no problem that both headers include each other.

Accessing GUI components through C++ code in VC++

I have created a Windows Form Project in VC++ 2010 Express version. So, in that project I created a Form, which had only 1 button and 1 textbox. The name of this form was Form1.
This button called a function FD written in a .cpp file in the same project. However, while running the code, I need to update the textbox with some text. I want to access the textbox through the .cpp file.
I have tried the following:
I included #include "Form1.h" and then wrote textBox1->Text="XYZ". However, while building it says that it cannot find any member called textBox1.
How do I access the textbox from the .cpp file?
EDIT:
FD.cpp
#include<stdafx.h>
#include "Form1.h"
... //other includes
void abc()
{
//Some code
textBox1->Text="String to be displayed."
//Some code
}
Form1.h
This is simple GUI form, where a button called button1 and a textbox called textBox1 is added.
#include<FD.h>
//code generated by the GUI
void button1_click()
{
abc();
}
// FD.cpp
void abc(Form1^ f)
{
// Assuming that textBox1 is public. If not, make it public or make
// public get property
f->textBox1->Text="String to be displayed."
//Some code
}
// Form1.h
void button1_click()
{
abc(this);
}
Or:
// FD.cpp
void abc(TextBox^ t)
{
t->Text="String to be displayed."
//Some code
}
// Form1.h
void button1_click()
{
abc(textBox1);
}
Another way: make abc method return type String^ and set its return value in Form1 to textBox1. Advantage: abc doesn't know anything about UI level. Yet another way: events http://msdn.microsoft.com/en-us/library/58cwt3zh.aspx
The reason you're getting this error is because you haven't specified whose textBox that is. It is not enough to #include the header file, you need to find a way to communicate with your Form1 object. You can do this in several ways.
Using a global pointer to the instance of your main Form1 that can be accessed from anywhere,
Using a local pointer to the instance of your main Form1 that is passed around and can be called upon,
Providing a friend function that can manipulate the data in the class (not recommended),
I would choose 2.