Orbiter-Forum  

Go Back   Orbiter-Forum > Orbiter Space Flight Simulator > Orbiter SDK
Register Blogs Orbinauts List Social Groups FAQ Projects Mark Forums Read

Orbiter SDK Orbiter software developers post your questions and answers about the SDK, the API interface, LUA, meshing, etc.

Reply
 
Thread Tools
Old 01-05-2017, 09:23 AM   #1
birdman
Orbinaut
Default Get handle to vessel in different class than where it's initialised

Hey you all,

I am new to the orbiter-forum and programming own parts and started a few days ago. I already checked the forum for solutions. But I didn't get to solve the problem. So now I'm here and hope you can help me.

At the moment I want to create a ReentrySystem which can call values of the vessel in view.
For this I created a class ReentrySystem with its own methods.

First things first: When I compile and build the code, it shows no errors.

Now when I call the function in Orbiter, which activates the ReentrySystem it calls correctly the method defined in the ReentrySystem class, but as soon as it needs to call a value of the vessel like this:
class->GetAltitude();
Orbiter crashes. I dont really understand why. I guess that the reference to the class is NULL.
Sometimes it showed me in the DebugString the initialised parameter value 0.000, but on further execution of my test scenario, without making any changes, it crashed again

The function "ReentrySystem::clbkRESPreStep()" gets called in the vessel .cpp file while executing the
clbkPreStep (double SimT, double SimDT, double mjd) function.

Maybe at this point it is easier to ask how to get the handle of the vessel stored in another class so that I can get the parameteres of the vessel in view. Or if i can call the handle to the vessel in view directly?
Or is this not possible because I will get an access error, because to parts of the programm want to use the handle of the vessel?

Down below is my current try of the ReentrySystem. But i guess with this call I don't get the handle of the vessel in view.

Code:
// Header file of Reentry System

#pragma once

#include "Orbitersdk.h"

class ReentrySystem {

public:
	ReentrySystem(VESSEL3* pVes);
	~ReentrySystem();
	virtual void clbkRESPreStep();	// Called after every time step to get actual parameter data
	void GetCMAltitude();
	//inline const VESSEL3* GetVessel() const { return vessel; }

	
private:
	
	// Global variables:
	// Vessel Parameters
	// Reference

	VESSEL3* pMe;
	double myAlt;

};

Code:
// .cpp file of Reentry System

#include "ReentrySystem.h"

// Constructor of ReentrySystem
ReentrySystem::ReentrySystem(VESSEL3* pVes)
{

	// Assign reference objects to local member variables
	pMe = pVes;
	// Initialise value
	myAlt = 0;
}


// Destructor ReentrySystem
ReentrySystem::~ReentrySystem()	{
	}


void ReentrySystem::clbkRESPreStep()
{
	myAlt = pMe->GetAltitude(); // Not working
	sprintf(oapiDebugString(), "Momentane Höhe über Grund %f", myAlt);
}

I'm sorry if this is confusing. Please feel free to ask for anything I may have forgotten to add.

Thanks in advance for your answers


EDIT:
So as i found out. If i close the orbiter simulator by force (killing the task). I always get the value 0.00000

If I don't do that and go into debug mode. It is shown to me that I get this message:

Unhandled exception at 0x6C55C6C0 in orbiter.exe: 0xC0000005: Access violation reading location 0x00730081

So it seems like I'm getting the (un)expected NULL pointer

Last edited by birdman; 01-06-2017 at 01:08 PM.
birdman is offline   Reply With Quote
Old 01-14-2017, 07:06 PM   #2
blacek
Orbinaut
Default

Hi birdman, I am new to this environment as well, and this is my first post.
It looks like either the VESSEL3 object that you are passing into your ReentrySystem constructor is either not created at the time that you are calling clbkRESPreStep(), or the object itself is being de-allocated at some point after.
First off, in general you should initialize your data members via memberwise init:
ReentrySystem::ReentrySystem() : pMe(NULL), myAlt(0.) {
Secondly, always make sure to defensively protect against NULL, so in your call to clbkRESPreStep(): add a check like this: if(pMe) myAlt=pMe->GetAltitude();

I feel there may be some timing issue here, since you are calling clbkRESPreStep() on some timer (according to your comment), and perhaps there is no VESSEL3 object fully instantiated yet.

You should review when you are starting up the timer as well...might want to wait until all relevant objects have been created, etc.

Also, if there is some multithreading involved, then there may very well be some race condition, or minimally a timing issue.

Hey birdman,
Like I said, I am absolutely new to this environment, but in just reviewing some of the SDK, I am wondering if you should be subclassing VESSEL3, rather than compositing.
My previous advice is generally good practice anyway, but consider subclassing...

Last edited by PhantomCruiser; 01-15-2017 at 09:39 AM.
blacek is offline   Reply With Quote
Old 01-31-2017, 01:25 PM   #3
birdman
Orbinaut
Default

Hi blacek,

thank you for your answer.
In the meantime I solved my problem.
It was a total rookie mistake with pointer initialisation.

The problem was in the program part, which I didn't post here.

To be able to use the functions/methods of the reentry system class in the main programm, without making it a subclass of the ship class, I initialised a pointer to the reentrysystem class. But I forgot to create a new class object. So my pointer was pointing to memory cells in a random manner.
Seems like I can hardly blame it for doing so

So simply I solved my problem by doing this:

Code:
// spaceshipclass.h
#include "ReentrySystem.h"

/* Spaceship class */
class spaceship : public VESSEL3 {
public:
spaceship(OBJHANDLE hVessel, int flightmodel);


private:
ReentrySystem*		reentry;		// provides data for reentry mode 
};
Code:
// spaceship.cpp
#include "spaceshipclass.h"

// Constructor
spaceship::spaceship (OBJHANDLE hVessel, int flightmodel)
	: VESSEL3 (hVessel, flightmodel){


// Part I simply forgot to implement
/* Set up the ReentrySystem*/
reentry = new ReentrySystem(this);

}

Thanks again for your answer.
You were right. Not all necessary objects were created yet, because I didn't create them at all

In the meantime there is a query implemented, which checks if the vessel/pointer to the vesselclass, is not NULL
birdman is offline   Reply With Quote
Old 02-13-2017, 02:48 PM   #4
martins
Orbiter Founder
Default

This may be obvious, in which case please ignore, but since you mentioned that you were new to programming: after creating the reentry object dynamically in the constructor, make sure you delete it in the destructor, to avoid memory leaks.

In general it's good practice to consider the scope and lifetime of your dynamic objects and match every "new" with the corresponding "delete". It's easy to forget. Or you could use a smart pointer that takes care of deleting the object when its (last) pointer goes out of scope.
martins is offline   Reply With Quote
Reply

  Orbiter-Forum > Orbiter Space Flight Simulator > Orbiter SDK

Tags
c++, handle to vessel, parameters of classes


Thread Tools

Posting Rules
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Jump


All times are GMT. The time now is 12:06 PM.

Quick Links Need Help?


About Us | Rules & Guidelines | TOS Policy | Privacy Policy

Orbiter-Forum is hosted at Orbithangar.com
Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright ©2007 - 2017, Orbiter-Forum.com. All rights reserved.