I'm trying to build a game that uses SDL2 (which compiles fine, but I get seg fault when executing the binary file) and SFML (which I can't get to compile successfully).
These are the errors I get:
pi#raspberrypi:~/spaceinvaders $ scons --use_sfml
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o audio/player.o -c -Wextra -I. -DUSE_BOOST_CHRONO -DBOOST_SP_DISABLE_THREADS -DTIXML_USE_STL -O3 -DUSE_SFML -DNDEBUG audio/player.cpp
audio/player.cpp: In member function 'sf::SoundBuffer oci::audio::{anonymous}::Loader::operator()(const string&)':
audio/player.cpp:52:16: error: 'class sf::SoundBuffer' has no member named 'LoadFromMemory'
audio/player.cpp: In constructor 'oci::audio::{anonymous}::ControllerImpl::ControllerImpl(const sf::SoundBuffer&, bool, bool)':
audio/player.cpp:61:24: error: no matching function for call to 'sf::Sound::Sound(const sf::SoundBuffer&, bool&)'
audio/player.cpp:61:24: note: candidates are:
/usr/local/include/SFML/Audio/Sound.hpp:69:5: note: sf::Sound::Sound(const sf::Sound&)
/usr/local/include/SFML/Audio/Sound.hpp:69:5: note: candidate expects 1 argument, 2 provided
/usr/local/include/SFML/Audio/Sound.hpp:61:14: note: sf::Sound::Sound(const sf::SoundBuffer&)
/usr/local/include/SFML/Audio/Sound.hpp:61:14: note: candidate expects 1 argument, 2 provided
/usr/local/include/SFML/Audio/Sound.hpp:53:5: note: sf::Sound::Sound()
/usr/local/include/SFML/Audio/Sound.hpp:53:5: note: candidate expects 0 arguments, 2 provided
audio/player.cpp:64:20: error: 'class sf::Sound' has no member named 'Play'
audio/player.cpp: In member function 'virtual bool oci::audio::{anonymous}::ControllerImpl::IsPlaying() const':
audio/player.cpp:68:23: error: 'const class sf::Sound' has no member named 'GetStatus'
audio/player.cpp: At global scope:
audio/player.cpp:77:1: error: 'shared_ptr' in namespace 'std' does not name a type
scons: *** [audio/player.o] Error 1
scons: building terminated because of errors.
The code has been updated last time in 2015, so I assume it is using some older SFML version (which i don't know) and in the latest version some functions have been changed and the compatibility broke. I can't test older versions because there is only one version available for RPi3 (2.4) .
audio/player.cpp file:
#include "player.h"
#ifdef USE_SFML
# include <SFML/Audio/Sound.hpp>
# include <SFML/Audio/SoundBuffer.hpp>
#else
# include <SDL2/SDL_mixer.h>
#endif
#include <portability/cpp11.h>
#include <resources/loader.h>
#include <stdexcept>
#include <utils/cache.h>
namespace oci {
namespace audio {
#ifdef USE_SFML
namespace {
class Loader {
public:
sf::SoundBuffer operator()(const std::string& name) {
std::vector<char> data =
resources::ResourcesLoader::Instance().GetData("sfx/" + name);
if(data.empty())
throw std::logic_error("Sound resource \"sfx/" + name +
"\" is empty");
sf::SoundBuffer sb;
if(!sb.LoadFromMemory(&data[0], data.size()))
throw std::logic_error("Cannot load sound \"" + name + "\"");
return sb;
}
};
class ControllerImpl : public Controller {
public:
ControllerImpl(const sf::SoundBuffer& sb, bool autoplay, bool loop) :
mSound(sb, loop)
{
if(autoplay)
mSound.Play();
}
virtual bool IsPlaying() const override {
return mSound.GetStatus() == sf::Sound::Playing;
}
private:
sf::Sound mSound;
};
} // namespace
std::shared_ptr<Controller> Play(const std::string& name, bool autoplay,
bool loop) {
static Cache<sf::SoundBuffer, Loader> cache;
const sf::SoundBuffer& sb = cache.Get(name);
return std::make_shared<ControllerImpl>(sb, autoplay, loop);
}
#else
// SDL audio code, not needed
#endif
} // namespace audio
} // namespace oci
Related
I am working on a project which uses the LLVM YAML I/O library. This is the documentation/tutorial that I am following:
https://www.llvm.org/docs/YamlIO.html
I am trying to replicate the example where you define a specialization on llvm::yaml::MappingTraits for a struct data type. This example is at the top of the page.
This is my code that I have written:
#include <cstdlib> /* for EXIT_FAILURE */
#include <string>
#include <vector>
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/YAMLParser.h"
using std::string;
using std::vector;
using llvm::outs;
using llvm::errs;
using llvm::yaml::ScalarEnumerationTraits;
using llvm::yaml::MappingTraits;
using llvm::yaml::IO;
using llvm::yaml::Input;
using llvm::yaml::Output;
struct Person {
string name;
int hatSize;
};
template <>
struct MappingTraits<Person> {
static void mapping(IO& io, Person& info) {
io.mapRequired("name", info.name);
io.mapOptional("hat-size", info.hatSize);
}
};
int main(int argc, const char **argv) {
Person tom;
tom.name = "Tom";
tom.hatSize = 8;
Person dan;
dan.name = "Dan";
dan.hatSize = 7;
std::vector<Person> persons;
persons.push_back(tom);
persons.push_back(dan);
Output yout(llvm::outs());
yout << persons;
return EXIT_SUCCESS;
}
It seems to me that I have replicated the example code that they have in that tutorial exactly. But when I try to compile the program (using makefile) I get this cryptic error message:
clang++ -I/usr/local/include -std=c++11 -fno-exceptions -fno-rtti -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -std=c++14 -fcxx-exceptions -g -Wall -c -o yaml_project.o yaml_project.cpp
In file included from yaml_project.cpp:12:
/usr/local/include/llvm/Support/YAMLTraits.h:1871:36: error: implicit instantiation of undefined template 'llvm::yaml::MissingTrait<std::vector<Person, std::allocator<Person> > >'
char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
^
yaml_project.cpp:153:10: note: in instantiation of function template specialization 'llvm::yaml::operator<<<std::vector<Person, std::allocator<Person> > >' requested here
yout << persons;
^
/usr/local/include/llvm/Support/YAMLTraits.h:307:8: note: template is declared here
struct MissingTrait;
^
1 error generated.
<builtin>: recipe for target 'yaml_project.o' failed
make: *** [yaml_project.o] Error 1
I don't think that the error is in the command that I am using to compile this program, because it has worked for me before to compile and link the LLVM libraries into my executable. I think that the problem is in the code, but I cannot identify what.
The code for the mentioned header file llvm/Support/YAMLTraits.h is here:
https://llvm.org/doxygen/YAMLTraits_8h_source.html
Reading the documentation, it seems to me that support for your specific vector<Person> requires registration with a macro:
LLVM_YAML_IS_SEQUENCE_VECTOR(Person)
// or
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(Person)
See, Utility Macros: https://llvm.org/docs/YamlIO.html#id22
I am trying to create a class which calls one of it's functions when created, but I am getting the following error when compiling:
g++ -std=c++11 -Wall -Wextra -Werror -pedantic-errors -DNDEBUG -c src/PuzzleSolution.cpp
src/PuzzleSolution.cpp:7:32: error: definition of implicitly-declared 'PuzzleSolution::PuzzleSolution()'
PuzzleSolution::PuzzleSolution()
^
src/PuzzleSolution.cpp:12:6: error: prototype for 'void PuzzleSolution::addRow()' does not match any in class 'PuzzleSolution'
void PuzzleSolution::addRow()
^
src/PuzzleSolution.h:19:10: error: candidate is: void PuzzleSolution::addRow(std::vector<unsigned int>&)
explicit PuzzleSolution();
^
src/PuzzleSolution.cpp:17:48: error: no 'void PuzzleSolution::addElement(unsigned int)' member function declared in class 'PuzzleSolution'
void PuzzleSolution::addElement(unsigned int id)
^
make: *** [PuzzleSolution.o] Error 1
Here is the header:
#include <vector>
using namespace std;
class PuzzleSolution {
private:
vector<vector<unsigned int>> sol;
public:
explicit PuzzleSolution();
void addRow();
};
Here is the cpp file:
#include "PuzzleSolution.h"
PuzzleSolution::PuzzleSolution()
{
addRow();
}
void PuzzleSolution::addRow()
{
this->sol.emplace_back();
}
What am I doing wrong?
The code as it is has no error. It compiles with GCC 4.8.2
Be sure that your header file is indeed what you have linked to. Most likely the header being included is different than the one you have actually posted here.
Side Note: Generally it is considered as a bad practice to put using namespace std; in a header file.
Found the issue:
There was a file in the src folder called PuzzleSolution.h.gch
#Quatin and #StoryTeller helped me to understand that this is a pre-compiled header, which the compiler kept using.
Once deleted, the project compiled and executed
I'm writing software to control a bladeRF radio card but I'm running into a strange compiler/linker error that I haven't been able to figure out. My code uses several functions and data structures defined in the library, libbladeRF, but for some reason I can't reference to one specific function.
However, if I modify the call with an improper argument type, g++ will throw an error to let me know that it doesn't conform to the definition, which seems to tell me that the linker is actually able to locate the reference.
What am I missing?
Initial error:
$ g++ bladeRF_test.cpp -o bladeRF_test -lbladeRF
/tmp/ccTWZzdJ.o: In function `enable_xb300()':
bladeRF_test.cpp:(.text+0x36a): undefined reference to `bladerf_xb300_set_amplifier_enable'
Code excerpt:
#include <iostream>
#include <string>
#include <libbladeRF.h>
using namespace std;
...
int set_xb300_pa(bool enable) {
bladerf_xb300_amplifier amp = BLADERF_XB300_AMP_PA;
if ( bladerf_xb300_set_amplifier_enable(dev, amp, enable) ) {
// Print error message
return -1;
} else {
// Print success message
return 0;
}
}
...
Function arguments changed from (dev, amp, enable) to (&dev, amp, enable):
$ g++ blade_hello.cpp -o blade_hello -lbladeRF
blade_hello.cpp: In function ‘int set_xb300_pa()’:
blade_hello.cpp:62:59: error: cannot convert ‘bladerf**’ to ‘bladerf*’ for argument ‘1’ to ‘int bladerf_xb300_set_amplifier_enable(bladerf*, bladerf_xb300_amplifier, bool)
^
In file included from blade_hello.cpp:4:0:
/usr/local/include/libbladeRF.h:2226:15: note: declared here
int CALL_CONV bladerf_xb300_set_amplifier_enable(struct bladerf *dev,
^
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.
This error is inexplicably occurring. Here is the code and output:
timer.cpp:
#include "timer.h"
#include "SDL.h"
#include "SDL_timer.h"
void cTimer::recordCurrentTime()
{
this->previous_t = this->current_t;
this->current_t = SDL_GetTicks();
}
timer.h:
#include "SDL.h"
#include "SDL_timer.h"
class cTimer
{
private:
int previous_t;
int current_t;
float delta_time;
float accumulated_time;
int frame_counter;
public:
void recordCurrentTime();
float getDelta();
void incrementAccumulator();
void decrementAccumulator();
bool isAccumulatorReady();
void incrementFrameCounter();
void resetFrameCounter();
int getFPS();
};
Compiler errors:
make
g++ -Wall -I/usr/local/include/SDL -c timer.cpp
timer.cpp: In member function ‘void cTimer::recordCurrentTime()’:
timer.cpp:6: error: ‘class cTimer’ has no member named ‘previous_t’
timer.cpp:6: error: ‘class cTimer’ has no member named ‘current_t’
timer.cpp:7: error: ‘class cTimer’ has no member named ‘current_t’
make: *** [timer.o] Error 1
Compiler errors after removing the #include "timer.h"
g++ -Wall -I/usr/local/include/SDL -c ctimer.cpp
ctimer.cpp:4: error: ‘cTimer’ has not been declared
ctimer.cpp: In function ‘void recordCurrentTime()’:
ctimer.cpp:5: error: invalid use of ‘this’ in non-member function
ctimer.cpp:5: error: invalid use of ‘this’ in non-member function
ctimer.cpp:6: error: invalid use of ‘this’ in non-member function
make: *** [ctimer.o] Error 1
Works for me. Are you sure you've got the right timer.h? Try this:
cat timer.h
and verify that it's what you think it is. If so, try adding ^__^ at the beginning of your .h file and seeing if you get a syntax error. It should look something like this:
[/tmp]> g++ -Wall -I/tmp/foo -c timer.cpp
In file included from timer.cpp:1:
timer.h:1: error: expected unqualified-id before ‘^’ token
This seems very odd as
class cTimer
{
private:
int previous_t;
int current_t;
float delta_time;
float accumulated_time;
int frame_counter;
public:
void recordCurrentTime();
float getDelta();
void incrementAccumulator();
void decrementAccumulator();
bool isAccumulatorReady();
void incrementFrameCounter();
void resetFrameCounter();
int getFPS();
};
void cTimer::recordCurrentTime()
{
this->previous_t = this->current_t;
this->current_t = SDL_GetTicks();
}
Compiles OK for me.
This suggests that the compiler think cTimer is different from what you've put in your header. So maybe its getting a definition of cTimer from another source file? For this to be the case your "timer.h" would have to not be gettting included correctly. So maybe the wrong timer.h.
A way to check this would be to save the compiler preprocessor output and search that for cTimer.
Another option might be to put a syntax error in your timer.h and make sure the compile fails.
Anyway hope this helps
Some compilers have their own timer.h, this is a name conflict.
Or it is a something else of bizarre bug...
Try renaming timer.h and timer.cpp to something more descriptive like ClassTimer.h and ClassTimer.cpp, maybe the compiler is linking another file named 'timer' since it is a very generic name. Also try this in timer.cpp:
void cTimer::recordCurrentTime(void)
{
this->previous_t = this->current_t;
this->current_t = SDL_GetTicks();
}
Edit: code edited