This is a very odd and specific circumstance but, I recently exposed some of the classes from SFML (I hope that's allowed) to Lua with a C++ header-only library called LuaBridge (
https://github.com/vinniefalco/LuaBridge). Most of the classes were exposed just fine (but
sf::Event because LuaBridge doesn't like Enums or Unions), but after trying to use
sf::Text I get an error. My error is that I get a Segmentation Fault after I create a
sf::Text object, then set the font with a
sf::Font object (and no, the reference isn't destroyed because this doesn't happen with
sf::Texture and
sf::Sprite).
Here is my C++ code to expose some SFML classes, and run a lua script called
script.lua:
#include <string>
#include <SFML/Graphics.hpp>
#include <lua.hpp>
#include <LuaBridge.h>
//Wrapper for sf::Text:
class TextWrap
{
private:
sf::Text member;
public:
void setCharacterSize(const int& newSize) {member.setCharacterSize(newSize);}
int getCharacterSize() {return member.getCharacterSize();}
void setColor(const sf::Color& newColor) {member.setColor(newColor);}
sf::Color getColor() {return member.getColor();}
void setFont(const sf::Font& newFont) {member.setFont(newFont);}
const sf::Font* getFont() {return member.getFont();}
void setPosition(const sf::Vector2f& newPosition) {member.setPosition(newPosition);}
sf::Vector2f getPosition() {return member.getPosition();}
void setRotation(const float& rotation) {member.setRotation(rotation);}
float getRotation() {return member.getRotation();}
void setScale(const sf::Vector2f& newScale) {member.setScale(newScale);}
sf::Vector2f getScale() {return member.getScale();}
void setString(const std::string& text) {member.setString(text);}
std::string getString() {return member.getString();}
void move(const sf::Vector2f& movePos) {member.move(movePos);}
void rotate(const float& rotation) {member.rotate(rotation);}
void scale(const sf::Vector2f& scaleAmount) {member.scale(scaleAmount);}
sf::Text getMember() {return member;}
};
class WindowWrap
{
private:
sf::RenderWindow member;
public:
void createWindowed(const unsigned int width, const unsigned int height, const std::string& title)
void close() {member.close();}
void clear(const sf::Color& clearColour) {member.clear(clearColour);}
void display() {member.display();}
void draw(TextWrap& text) {member.draw(text.getMember());}
};
int main()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
luabridge::getGlobalNamespace(L)
.beginClass<sf::Vector2f>("Vector2f")
.addConstructor<void(*)(float, float)>()
.addData("x", &sf::Vector2f::x)
.addData("y", &sf::Vector2f::y)
.endClass()
.beginClass<sf::Vector2i>("Vector2i")
.addConstructor<void(*)(int, int)>()
.addData("x", &sf::Vector2i::x)
.addData("y", &sf::Vector2i::y)
.endClass()
.beginClass<sf::Color>("Color")
.addConstructor<void(*)(unsigned int, unsigned int, unsigned int, unsigned int)>()
.addData("r", &sf::Color::r)
.addData("g", &sf::Color::g)
.addData("b", &sf::Color::b)
.addData("a", &sf::Color::a)
.endClass()
.beginClass<sf::Font>("Font")
.addConstructor<void(*)(void)>()
.addFunction("loadFromFile", &sf::Font::loadFromFile)
.endClass()
.beginClass<TextWrap>("Text")
.addConstructor<void(*)(void)>()
.addFunction("setCharacterSize", &TextWrap::setCharacterSize)
.addFunction("getCharacterSize", &TextWrap::getCharacterSize)
.addFunction("setColor", &TextWrap::setColor)
.addFunction("getColor", &TextWrap::getColor)
.addFunction("setFont", &TextWrap::setFont)
.addFunction("getFont", &TextWrap::getFont)
.addFunction("setPosition", &TextWrap::setPosition)
.addFunction("getPosition", &TextWrap::getPosition)
.addFunction("setRotation", &TextWrap::setRotation)
.addFunction("getRotation", &TextWrap::getRotation)
.addFunction("setScale", &TextWrap::setScale)
.addFunction("getScale", &TextWrap::getScale)
.addFunction("setString", &TextWrap::setString)
.addFunction("getString", &TextWrap::getString)
.addFunction("move", &TextWrap::move)
.addFunction("rotate", &TextWrap::rotate)
.addFunction("scale", &TextWrap::scale)
.endClass()
.beginClass<WindowWrap>("Window")
.addConstructor<void(*)(void)>()
.addFunction("createWindowed", &WindowWrap::createWindowed)
.addFunction("close", &WindowWrap::close)
.addFunction("clear", &WindowWrap::clear)
.addFunction("display", &WindowWrap::display)
.addFunction("draw", &WindowWrap::draw)
.endClass();
WindowWrap mainWindow; //This is defined here so C++ knows if the main application is open
mainWindow.createWindowed(800, 600, "Lua Test");
luabridge::push(L, &mainWindow);
lua_setglobal(L, "mainWindow");
luaL_dofile(L, "./script.lua");
}
Here is
script.lua:
text = Text();
text:setCharacterSize(16);
text:setPosition(Vector2f(100, 100));
text:setColor(Color(255,255,255,255));
text:setString("Hello World");
font = Font();
font:loadFromFile("./font.ttf");
text:setFont(font); --If I remove this I don't get a Segmentation Fault
mainWindow:drawText(text); --But the Segmentation Fault happens here
The chances of someone being familiar with C++, SFML, LuaBridge and Lua are very low, so I don't expect someone to know exactly why, but just to have an idea or suggestion.
Details I forgot:
- OS: Ubuntu 14.04
- Graphics Card: NVIDIA GTX 750 Ti (Not sure if it matters)
- SFML Version: 2.1
Debugger Callstack:
#0 0x7ffff7bb4dcc sf::Font::getTexture(unsigned int) const() (/usr/lib/x86_64-linux-gnu/libsfml-graphics.so.2:??)
#1 0x7ffff7bcdd3e sf::Text::draw(sf::RenderTarget&, sf::RenderStates) const() (/usr/lib/x86_64-linux-gnu/libsfml-graphics.so.2:??)
#2 0x7ffff7bc6b17 sf::RenderTarget::draw(sf::Drawable const&, sf::RenderStates const&) () (/usr/lib/x86_64-linux-gnu/libsfml-graphics.so.2:??)
#3 0x407439 WindowWrap::drawText(this=0x7fffffffe0f0, text=...) (/home/ben/Documents/Programming/C++/Projects/TEST/main.cpp:56)
#4 0x410686 luabridge::FuncTraits<void (WindowWrap::*)(TextWrap&) (../../Resources/External/Cross-Platform/LuaBridge/detail/FuncTraits.h:209)
#5 0x40e774 luabridge::CFunc::CallMember<void (WindowWrap::*)(TextWrap&) (../../Resources/External/Cross-Platform/LuaBridge/detail/CFunctions.h:313)
#6 0x7ffff756561d ??() (/usr/lib/x86_64-linux-gnu/liblua5.2.so.0:??)
#7 0x7ffff75709b4 ??() (/usr/lib/x86_64-linux-gnu/liblua5.2.so.0:??)
#8 0x7ffff7565989 ??() (/usr/lib/x86_64-linux-gnu/liblua5.2.so.0:??)
#9 0x7ffff7564fac ??() (/usr/lib/x86_64-linux-gnu/liblua5.2.so.0:??)
#10 0x7ffff7565bc1 ??() (/usr/lib/x86_64-linux-gnu/liblua5.2.so.0:??)
#11 0x7ffff7561c9d lua_pcallk() (/usr/lib/x86_64-linux-gnu/liblua5.2.so.0:??)
#12 0x404523 main() (/home/ben/Documents/Programming/C++/Projects/TEST/main.cpp:181)