A friend and I are making a simple multiplayer game to practice our coding. Unfortunately we have encountered a problem. The SFML threading system (Not using std::thread because my compiler doesn't support it yet) is giving me an error.
||=== Build: Debug in Clear Void (compiler: GNU GCC Compiler) ===|
C:\Users\Name\Documents\Coding\SFML work\Clear_Void\src\GameScreen.cpp||In constructor 'GameScreen::GameScreen()':|
C:\Users\Name\Documents\Coding\SFML work\Clear_Void\src\GameScreen.cpp|9|error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&GameScreen::startThread' [-fpermissive]|
C:\SFML-TDM471x32\include\SFML\System\Thread.inl||In instantiation of 'void sf::priv::ThreadFunctor::run() [with T = void (GameScreen::*)()]':|
C:\Users\Name\Documents\Coding\SFML work\Clear_Void\src\GameScreen.cpp|53|required from here|
C:\SFML-TDM471x32\include\SFML\System\Thread.inl|39|error: must use '.' or '->' to call pointer-to-member function in '((sf::priv::ThreadFunctor)this)->sf::priv::ThreadFunctor::m_functor (...)', e.g. '(... -> ((sf::priv::ThreadFunctor*)this)->sf::priv::ThreadFunctor::m_functor) (...)'|
||=== Build failed: 2 error(s), 2 warning(s) (0 minute(s), 4 second(s)) ===|
Here is my code:
GameScreen.h
class GameScreen : public Screen
{
public:
GameScreen();
void handleInput(sf::RenderWindow&) override;
void update(sf::RenderWindow&, sf::View&) override;
void render(sf::RenderWindow&) override;
void startThread();
private:
sf::Vector2f moveVal;
Network network;
Events eventManager;
Map m_map;
sf::Thread networkThread;
};
GameScreen.cpp (Relevant Section)
GameScreen::GameScreen()
: networkThread(&startThread)
{
network.Connect();
}
I checked the SFML threading tutorials and according to them, that should work. Please help.
startThread should be static. In general, thread functions can't call non-static member functions.
Related
I am trying to make a simple program to drop files on a list using C++ with a (wxWidgets) wxListCtrl.
Tools I use: Code::Blocks 20.03, MinGW 17.1, wxWidgets 3.1.3, wxFormBuilder 3.9.0.
OS: Windows 10 Pro.
I tried the following: (in a function SetupGUI() which is called in the DnD_SimpleFrame class constructor.)
m_listCtrl1 = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_HEADER|wxLC_REPORT );
m_listCtrl1->DragAcceptFiles(true);
m_listCtrl1->Connect(wxEVT_DROP_FILES, wxDropFilesEventHandler(DnD_SimpleFrame::OnDropFiles), NULL, this);
The function to be called on dropping the files (from explorer) is:
bool DnD_SimpleFrame::OnDropFiles(wxArrayString &filenames)
{
size_t nFiles = filenames.GetCount();
wxString str;
str.Printf( "%d files dropped", (int)nFiles);
m_listCtrl1->DeleteAllItems();
if (m_listCtrl1 != NULL)
{
m_listCtrl1->InsertItem(0, str);
for ( size_t n = 1; n < (nFiles+1); n++ )
m_listCtrl1->InsertItem(n, filenames[n]);
}
return true;
}
The build messages on the m_listCtrl1->Connect(...); line are:
||=== Build: Debug in DnD_Simple (compiler: GNU GCC Compiler) ===|
F:\Data\__C++\wxApps\DnD_Simple\DnD_SimpleMain.cpp||In member function 'void DnD_SimpleFrame::SetupGUI()':|
F:\SDKs\wx313\include\wx\event.h|149|error: invalid static_cast from type 'bool (DnD_SimpleFrame::*)(wxArrayString&)' to type 'wxDropFilesEventFunction' {aka 'void (wxEvtHandler::*)(wxDropFilesEvent&)'}|
F:\SDKs\wx313\include\wx\event.h|4196|note: in expansion of macro 'wxEVENT_HANDLER_CAST'|
F:\Data\__C++\wxApps\DnD_Simple\DnD_SimpleMain.cpp|92|note: in expansion of macro 'wxDropFilesEventHandler'|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|
What am I doing wrong here (or am forgetting)?
If you carefully look at the error message:
error: invalid static_cast from type 'bool (DnD_SimpleFrame::*)(wxArrayString&)' to type 'wxDropFilesEventFunction' {aka 'void (wxEvtHandler::*)(wxDropFilesEvent&)'}
you can see that it says that it can't convert something from one type to the other one.
The types may be difficult to parse if you're new to C++, but you should be able to see that these are function pointers (in fact, pointers to a class member). And looking at your code, you should also be able to see that the first is them is the type of your DnD_SimpleFrame::OnDropFiles function and hence the problem is that it can't be converted to the expected function type.
Finally, the reason for this is just that your function doesn't have the right parameter type: you're supposed to give wxWidgets something taking wxDropFilesEvent&, but your function takes wxArrayString& instead. You will have to change it to take wxDropFilesEvent& event and then use GetFiles() method of the event object to get the actual files.
On a completely different topic, you should use Bind() and not Connect() in the new code. If you're following a tutorial which uses the latter, it's a good sign that it's very outdated. Your code still wouldn't have compiled with Bind(), but the error messages would have been slightly simpler.
I'm using the unity framework to unittest my C code on an AtMega32A. This works great. now I wonder if I can somehow trick unity to also test my C++ code.
I've made a small proof of concept program that exposes all the members of the C++ class via a public function. Now I would like to put a number of assert macro's in that public function. The program can be found here:
https://github.com/cdwijs/cpp_unit_test
In my main I have the following:
int main(void)
{
UNITY_BEGIN();
//RUN_TEST(myPrivate.executeTest); //unity_internals.h(707,65): error: invalid use of non-static member function
//RUN_TEST((void*)myPrivate.executeTest); //error: invalid use of member function (did you forget the '()' ?)
//RUN_TEST((func)))myPrivate.executeTest); //error: 'func' was not declared in this scope
//RUN_TEST(&myPrivate.executeTest); //error: cannot convert 'void (Private::*)()' to 'UnityTestFunction {aka void (*)()}' for argument '1' to 'void UnityDefaultTestRun(UnityTestFunction, const char*, int)'
UNITY_END();
myPrivate.more();
myPrivate.more();
myPrivate.less();
/* Replace with your application code */
while (1)
{
}
}
And in Private_test.cpp I have the following:
#include "private.h"
#include "unity.h"
void Private::executeTest (void)
{
myNumber = 3;
TEST_ASSERT_EQUAL_INT(3,myNumber);
more();
TEST_ASSERT_EQUAL_INT(4,myNumber);
}
I can't figure out howto run the test function. Any Idea's? Am I looking in the correct direction, or should I use a test framework that is specifically aimed at C++?
I originally wrote some tests to test the functionality of signals for my program. The tests proved promising, however moving the small code changes to my class in my source code has given me a few problems.
I have added two functions: setAlarm(), and a callback alarm_handler. setAlarm() does as it says, which is set the alarm. Once time expires, alarm handler is called which runs an execute function.
a.cpp
int Database::alarm_handler(int signum)
{
dbExecSql();
}
void Database::setAlarm()
{
signal(SIGALRM, alarm_handler);
ualarm(500000,0);
}
b.h
class Database
{
public:
int alarm_handler(int signum);
void setAlarm();
dbExecSql();
};
error
error: invalid use of non-static member function
signal(SIGALRM, alarm_handler);
Any help would be appreciated.
EDIT
I have modified alarm_handler to be removed from my class, however am now am receiving:
error: invalid conversion from βint (*)(int)β to β__sighandler_t {aka void (*)(int)}β [-fpermissive]
signal(SIGALRM, alarm_handler);
^
The signal handler function (alarm_handler) can't be member function and should be a standalone function with C linkage.
Remove it from your class:
void alarm_handler(int signum)
{
dbExecSql();
}
Beware that only async-signal-safe functions can be called from signal handlers safely. So you need to ensure dbExecSql() respects that.
I stumbled across the below code and really found it complex to understand the nested macro and type casting in it.
Also when i tried to compile the code , i have encountered an error
Would need an explanantion of the below code.
why BEGIN_STATE_MAP and END_STATE_MAP set as labels in Motor.h , This is really new to me
Thanks in advance
Motor.h
// the Motor state machine class
class Motor : public StateMachine
{
public:
Motor() : StateMachine(ST_MAX_STATES) {}
// external events taken by this state machine
void Halt();
void SetSpeed(MotorData*);
private:
// state machine state functions
void ST_Idle();
void ST_Stop();
void ST_Start(MotorData*);
void ST_ChangeSpeed(MotorData*);
// state map to define state function order
BEGIN_STATE_MAP
STATE_MAP_ENTRY(ST_Idle)
STATE_MAP_ENTRY(ST_Stop)
STATE_MAP_ENTRY(ST_Start)
STATE_MAP_ENTRY(ST_ChangeSpeed)
END_STATE_MAP
// state enumeration order must match the order of state
// method entries in the state map
enum E_States {
ST_IDLE = 0,
ST_STOP,
ST_START,
ST_CHANGE_SPEED,
ST_MAX_STATES
};
};
#endif //MOTOR_H
what are BEGIN_STATE_MAP and END_STATE_MAP, This definition i found i really new,
BEGIN_STATE_MAP and END_STATE_MAP are the Macros defined in the below header file.
StateMachine.h
#ifndef STATE_MACHINE_H
#define STATE_MACHINE_H
#include <stdio.h>
#include "EventData.h"
struct StateStruct;
// base class for state machines
class StateMachine
{
public:
StateMachine(int maxStates);
virtual ~StateMachine() {}
protected:
enum { EVENT_IGNORED = 0xFE, CANNOT_HAPPEN };
unsigned char currentState;
void ExternalEvent(unsigned char, EventData* = NULL);
void InternalEvent(unsigned char, EventData* = NULL);
virtual const StateStruct* GetStateMap() = 0;
private:
const int _maxStates;
bool _eventGenerated;
EventData* _pEventData;
void StateEngine(void);
};
typedef void (StateMachine::*StateFunc)(EventData *);
struct StateStruct
{
StateFunc pStateFunc;
};
#define BEGIN_STATE_MAP \
public:\
const StateStruct* GetStateMap() {\
static const StateStruct StateMap[] = {
#define STATE_MAP_ENTRY(entry)\
{ reinterpret_cast<StateFunc>(entry) },
#define END_STATE_MAP \
{ reinterpret_cast<StateFunc>(NULL) }\
}; \
return &StateMap[0]; }
#define BEGIN_TRANSITION_MAP \
static const unsigned char TRANSITIONS[] = {\
#define TRANSITION_MAP_ENTRY(entry)\
entry,
#define END_TRANSITION_MAP(data) \
0 };\
ExternalEvent(TRANSITIONS[currentState], data);
#endif
EventData.h
#ifndef EVENT_DATA_H
#define EVENT_DATA_H
class EventData
{
public:
virtual ~EventData() {};
};
#endif //EVENT_DATA_H
While i tried to compile the code above.Below is the error that was encountered
Error
-------------- Build: Debug in StateMachine (compiler: GNU GCC Compiler)---------------
mingw32-g++.exe -Wall -fexceptions -g -pedantic -Wzero-as-null-pointer-constant -std=c++0x -Wextra -Wall -c C:\Users\xprk569\StateMachine\main.cpp -o obj\Debug\main.o
In file included from C:\Users\xprk569\StateMachine\main.cpp:2:0:
C:\Users\xprk569\StateMachine\Motor.h: In member function 'virtual const StateStruct* Motor::GetStateMap()':
C:\Users\xprk569\StateMachine\StateMachine.h:40:40: error: invalid use of member (did you forget the '&' ?)
{ reinterpret_cast<StateFunc>(entry) },
^
C:\Users\xprk569\StateMachine\Motor.h:29:9: note: in expansion of macro 'STATE_MAP_ENTRY'
STATE_MAP_ENTRY(ST_Idle)
^
C:\Users\xprk569\StateMachine\StateMachine.h:40:40: error: invalid use of member (did you forget the '&' ?)
{ reinterpret_cast<StateFunc>(entry) },
^
C:\Users\xprk569\StateMachine\Motor.h:30:9: note: in expansion of macro 'STATE_MAP_ENTRY'
STATE_MAP_ENTRY(ST_Stop)
^
C:\Users\xprk569\StateMachine\StateMachine.h:40:40: error: invalid use of member (did you forget the '&' ?)
{ reinterpret_cast<StateFunc>(entry) },
^
C:\Users\xprk569\StateMachine\Motor.h:31:9: note: in expansion of macro 'STATE_MAP_ENTRY'
STATE_MAP_ENTRY(ST_Start)
^
C:\Users\xprk569\StateMachine\StateMachine.h:40:40: error: invalid use of member (did you forget the '&' ?)
{ reinterpret_cast<StateFunc>(entry) },
^
C:\Users\xprk569\StateMachine\Motor.h:32:9: note: in expansion of macro 'STATE_MAP_ENTRY'
STATE_MAP_ENTRY(ST_ChangeSpeed)
^
C:\Users\xprk569\StateMachine\StateMachine.h:43:39: error: invalid cast from type 'int' to type 'StateFunc {aka void (StateMachine::*)(EventData*)}'
{ reinterpret_cast<StateFunc>(NULL) }\
^
C:\Users\xprk569\StateMachine\Motor.h:33:5: note: in expansion of macro 'END_STATE_MAP'
END_STATE_MAP
^
Process terminated with status 1 (0 minute(s), 0 second(s))
5 error(s), 0 warning(s) (0 minute(s), 0 second(s))
Can some please explain why is the macro written that way in Motor.h,
why is it declared like that in StateMachine.h and
why is the error being thrown ?
Thanks in Advance
It looks like this code depends on some nonstandard compiler extensions/errors.
To get it to compile (no idea if it will actually work) you need to replace the function names with full qualified member function pointers:
e.g.
BEGIN_STATE_MAP
STATE_MAP_ENTRY(&Motor::ST_Idle)
STATE_MAP_ENTRY(&Motor::ST_Stop)
STATE_MAP_ENTRY(&Motor::ST_Start)
STATE_MAP_ENTRY(&Motor::ST_ChangeSpeed)
END_STATE_MAP
After that, you need to figure out a way to overcome the non-conforming cast:
/tmp/gcc-explorer-compiler116314-75-1uiyu0/example.cpp: In member function 'virtual const StateStruct* Motor::GetStateMap()':
44 : error: invalid cast from type 'long int' to type 'StateFunc {aka void (StateMachine::*)(EventData*)}'
{ reinterpret_cast<StateFunc>(NULL) }\
^
83 : note: in expansion of macro 'END_STATE_MAP'
This cast is completely illegal. If I were you I would throw the code in the trash and rewrite - or use a proven state machine framework like boost meta state machine or boost statechart.
So you're quickly learning why Macros are no-nos in readable C++. If you get an error, you must expand the macro out to identify where the error is, also you cannot debug into them in most IDEs.
Anyway that said lets get to the expanding, their all the same error so we'll just look at the first one:
C:\Users\xprk569\StateMachine\Motor.h:29:9: note: in expansion of macro STATE_MAP_ENTRY
STATE_MAP_ENTRY(ST_Idle)
C:\Users\xprk569\StateMachine\StateMachine.h:40:40: error: invalid use of member (did you forget the & ?)
{ reinterpret_cast<StateFunc>(entry) },
So this is complaining about line 29: STATE_MAP_ENTRY(ST_Idle) So lets expand that:
{ reinterpret_cast<StateFunc>(entry) },
Obviously this is bad syntax all together outside the scoping of BEGIN_STATE_MAP and END_STATE_MAP, so in debugging many Macros you'd also have to look at the scoping macros... sometimes they may not be clearly named or delineated unfortunately, but let's finish defining the line we got the error on first. What is this StateFunc we're trying to cast to?
typedef void (StateMachine::*StateFunc)(EventData *);
It's a pointer to a member function which returns a void and accepts an EventData *. And alarm bells should be going off. You cannot cast to that! ST_Idle is of the format: void (StateMachine::*)() so you cannot cast to void (StateMachine::*StateFunc)(EventData *). This is the same problem for all your functions passed into the macros none of them return a void and take an EventData*, so even if you fix the syntax, these reinterpret_casts will always return a pointer to a method which is invalid to call, meaning this entire block of Macros is pointless at best and toxic at worst. In the current state you may just as well use none of these Macros or if you need to define the method just do:
BEGIN_STATE_MAP
END_STATE_MAP
But if you were going to change your method declarations to something more like:
void ST_Idle(EventData*);
Then you'd need to use this syntax:
STATE_MAP_ENTRY(&Motor::ST_Idle)
If you're not down with the method pointers they are quite complex. I've typed up a quick example here: http://ideone.com/nL0HnQ Feel free to comment with questions.
EDIT:
To expand the Macros here we'll get:
public: // BEGIN_STATE_MAP
const StateStruct* GetStateMap() { // BEGIN_STATE_MAP
static const StateStruct StateMap[] = { // BEGIN_STATE_MAP
{ reinterpret_cast<StateFunc>(ST_Idle) } // STATE_MAP_ENTRY(ST_Idle)
{ reinterpret_cast<StateFunc>(ST_Stop) } // STATE_MAP_ENTRY(ST_Stop)
{ reinterpret_cast<StateFunc>(ST_Start) } // STATE_MAP_ENTRY(ST_Start)
{ reinterpret_cast<StateFunc>(ST_ChangeSpeed) } // STATE_MAP_ENTRY(ST_ChangeSpeed)
{ reinterpret_cast<StateFunc>(NULL) } // END_STATE_MAP
}; // END_STATE_MAP
return &StateMap[0]; } // END_STATE_MAP
So this set of macros will:
Set the scope to public
Declare the method GetStateMap
Declare StateMap statically local to GetStateMap, it will be an array of StateStructs
On the first call of the GetStateMap method StateMap will be initialized to contain method pointers to ST_Idle, ST_Stop, ST_Start, ST_ChangeSpeed, and NULL reinterpret_cast to StateFuncs
Define GetStateMap to return the StateMap array
My actual question is in the bold text below, but here's the context of my problem:
I'm trying out Boost::serialization for saving and restoring a player's state. I read the tutorial at http://www.boost.org/doc/libs/1_56_0/libs/serialization/doc/tutorial.html#simplecase, but I'm not sure how
boost::archive::text_iarchive
works.
I'm working on the assumption that the following lines
boost::archive::text_iarchive inArchive(playerfile);
inArchive >> target;
will initialize the target according to the playerfile's corresponding textfile?
I'm wrote the following functions with that assumption:
bool SavePlayerState(Player *target)
{
std::string fileName = (target->name) + ".playerfile";
std::ofstream playerfile(fileName);
if(!playerfile.is_open())
{
s_al_show_native_message_box(display, "SAVE FAILURE", "SAVE FAILURE", fileName + "could not be created/opened.",
NULL, ALLEGRO_MESSAGEBOX_ERROR);
return false;
}
boost::archive::text_oarchive outArchive(playerfile);
outArchive << target;
return true;
}
bool LoadPlayerState(std::string playerName, Player *target)
{
std::string fileName = playerName + ".playerfile";
std::ifstream playerfile(fileName);
if(!playerfile.is_open())
{
s_al_show_native_message_box(display, "LOAD FAILURE", "LOAD FAILURE", fileName + "could not be found/opened.",
NULL, ALLEGRO_MESSAGEBOX_ERROR);
return false;
}
boost::archive::text_iarchive inArchive(playerfile);
inArchive >> target;
return true;
}
They are called in main() for testing purposes:
int main(int argc, char *argv[])
{
//...
player = new Player(5,5); // There is a Player*player; declared elsewhere
LoadPlayerState("player", player); //Load the file with this name, target is player object
beings.push_back(player);
//The game's operations...
SavePlayerState(player);
delete player;
//...
return 0;
}
SavePlayerState(player); works as I expected, and I find that player.playerfile has been created in my directory. But LoadPlayerState("player", player); gives me the following error:
C:\Development\Libraries\boost\boost\serialization\access.hpp|132|error: no matching function for call to 'Player::Player()'|
I don't know why the constructor should have problems, or why Save works and not Load. I'm not trying to make a new Player object, just shape the existing target Player according to the archive. What do I need to change in order to make this work?
My player class:
#ifndef PLAYER_H_INCLUDED
#define PLAYER_H_INCLUDED
#include "being.h"
#include "extfile.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/vector.hpp>
class Player: public Being
{
friend class boost::serialization::access;
template<class PlayerArchive>
void serialize(PlayerArchive & par, const unsigned int version)
{
par & boost::serialization::base_object<Being>(*this);
par & active;
//par & various things
}
public:
Player(bool savedPlayer);
Player(int spawnXCell, int spawnYCell);
~Player();
//Functions
};
//Prototype to the save and Load state functions mentioned previously are found here.
#endif // PLAYER_H_INCLUDED
Here is my complete build messages log, if it helps:
>||=== Build: Debug in Roguelike (compiler: GNU GCC Compiler) ===|
>C:\Development\Libraries\boost\boost\serialization\access.hpp||In instantiation of 'static void boost::serialization::access::construct(T*) [with T = Player]':|
>C:\Development\Libraries\boost\boost\serialization\serialization.hpp|93|required from 'void boost::serialization::load_construct_data(Archive&, T*, unsigned int) [with Archive = boost::archive::text_iarchive; T = Player]'|
>C:\Development\Libraries\boost\boost\serialization\serialization.hpp|158|required from 'void boost::serialization::load_construct_data_adl(Archive&, T*, unsigned int) [with Archive = boost::archive::text_iarchive; T = Player]'|
>C:\Development\Libraries\boost\boost\archive\detail\iserializer.hpp|341|required from 'void boost::archive::detail::pointer_iserializer::load_object_ptr(boost::archive::detail::basic_iarchive&, void*, unsigned int) const [with Archive = boost::archive::text_iarchive; T = Player]'|
>C:\Development\Projects\Roguelike\Roguelike\player.cpp|76|required from here|
>C:\Development\Libraries\boost\boost\serialization\access.hpp|132|error: no matching function for call to 'Player::Player()'|
>C:\Development\Libraries\boost\boost\serialization\access.hpp|132|note: candidates are:|
>C:\Development\Projects\Roguelike\Roguelike\player.cpp|8|note: Player::Player(int, int)|
>C:\Development\Projects\Roguelike\Roguelike\player.cpp|8|note: candidate expects 2 arguments, 0 provided|
>C:\Development\Projects\Roguelike\Roguelike\player.cpp|3|note: Player::Player(bool)|
>C:\Development\Projects\Roguelike\Roguelike\player.cpp|3|note: candidate expects 1 argument, 0 provided|
>C:\Development\Projects\Roguelike\Roguelike\player.h|12|note: Player::Player(const Player&)|
>C:\Development\Projects\Roguelike\Roguelike\player.h|12|note: candidate expects 1 argument, 0 provided|
||=== Build failed: 1 error(s), 5 warning(s) (0 minute(s), 4 second(s)) ===|
Thanks very much. If any other information is required, I will append it.
The error message is pretty clear:
no matching function for call to 'Player::Player()'
You must have a default constructor in your class.
In addition to what Joachim said, in some cases you will not be able to make a type default-constructible (especially when you're adding non-intrusive serialization to types from a 3rdparty library).
In that case learn about the load_construct_data customization point:
Non-default Constructors
This mechanism is already automatically employed for you e.g. in the deserialization of STL containers whose element type has no default constructor.