Rapptz / sol

A C++11 Lua wrapper
MIT License
209 stars 32 forks source link

Use of undeclared identifier 'lua_tounsigned' #75

Closed hdt80 closed 8 years ago

hdt80 commented 8 years ago

I'm creating a tower defense game that uses Lua as a scripting engine.

When compiling with both g++ and clang++ I get the following error.

include/sol/sol/stack.hpp:100:31: error: use of undeclared identifier "lua_tounsigned"
    return static_cast<U>(lua_tounsigned(L, index));

I am using the following command to compile:

g++ -Wall -Wno-format -Wno-unused-variable -c -g -O0 -fbuiltin -fpermissive -std=c++11 -I include -I src/include <FILES> -Llib <*snip*> -llua -o ./bin/Tower

I believe there error crops up when I'm defining my classes to use inside Lua. I created a class called LuaScript. Here are the .h and .cpp files

LuaScript.h

#ifndef _LUA_SCRIPT_H
#define _LUA_SCRIPT_H

#include <string>
#include "lua/selene.h"
#include "sol/sol.hpp"

class LuaScript {
public:
    LuaScript(bool loadedClasses = true);

    bool isLoaded() { return _loaded; }
    void setLoaded(bool b) { _loaded = b; }

    void loadScript(const std::string& name);

    sol::state lua;
protected:
    bool _loaded;

    void defineEnemy();
    void defineTower();
    void defineObject();
    void defineTarget();
    void defineMap();
    void defineStats();
};

#endif

LuaScript.cpp

#include "LuaScript.h"

<*Includes have been snipped*>

LuaScript::LuaScript(bool defineClasses) {
    _loaded = false;
    lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::table,
        sol::lib::package, sol::lib::math, sol::lib::debug);

    if (defineClasses) {
        defineTarget();
        defineObject();
        defineTower();
        defineEnemy();
        defineMap();
        defineStats();
    }
}

void LuaScript::loadScript(const std::string& name) {
    lua.open_file(name);
    setLoaded(true);
}

void LuaScript::defineTower() {
    sol::constructors<sol::types<Map*, float, float, Stats>> towerCon;
    sol::userdata<Tower> towerUserData (
        "Tower", towerCon,
        // Target methods
        "getX", &Tower::getX,
        "getY", &Tower::getY,
        "setPosition", &Tower::setPosition,
        "isSimpleTarget", &Tower::isSimpleTarget,
        // Object methods
        "contains", &Tower::contains,
        "applyStat", &Tower::applyStat,
        "setStats", &Tower::setStats,
        "getSpeed", &Tower::getSpeed,
        "getRange", &Tower::getRange,
        "getFireRate", &Tower::getFireRate,
        "getDamage", &Tower::getDamage,
        "getAccel", &Tower::getAccel,
        "getProjSpeed", &Tower::getProjSpeed,
        //"setRange", &Tower::setRange, // ERROR
        // Tower methods
        "getProjectile", &Tower::getProjectile,
        "setProjectile", &Tower::setProjectile
    );
    lua.set_userdata(towerUserData);
}

void LuaScript::defineObject() {
    <*snip*>
}

void LuaScript::defineTarget() {
    <*snip*>
}

void LuaScript::defineMap() {
    <*snip*>
}

void LuaScript::defineStats() {
    <*snip*>
}

void LuaScript::defineEnemy() {
    <*snip*>
}

All my Tower methods have been defined in Tower.cpp and Tower.h. Here are the relevant parts.

Tower.h

#ifndef _TOWER_H
#define _TOWER_H

#include "Target.h"
#include "Object.h"
#include "Stats.h"

class Tower : public Object {
public:
    <*I've removed all irrelevant code*>
    Tower(Map* map, float x, float y, Stats s);
    ~Tower();

    void loadLua();

    void setPosition(float x, float y);

    Object* getProjectile() { return _projectile; }
    void setProjectile(Object& o);

protected:
    <*snip*>
};
#endif

If I uncomment "setRange", &Tower::setRange I get the undeclared error, but commenting it out works fine.

Tower::setRange is set inside Object.h, the parent class of Tower.

Object.h

#ifndef _OBJECT_H
#define _OBJECT_H

<*Includes have been snipped*>

class Object : public Target, public sf::Drawable, public sf::Transformable {
public:
    Object();
    Object(Map* map, float x, float y, int collRadius, Stats s);
    virtual ~Object();

    <*snip*>

    int getSpeed() const { return _stats.speed + _baseStats.speed; }
    int getRange() const { return _stats.range + _baseStats.range; }
    float getFireRate() const { return _stats.fireRate + _baseStats.fireRate; }
    float getDamage() const { return _stats.damage + _baseStats.damage; }
    float getAccel() const { return _stats.accel + _baseStats.accel; }
    float getProjSpeed() const { return _stats.projSpeed + _baseStats.projSpeed; }
    // Stats setters
    void setRange(int r) { _stats.range = r; } // ERROR method
    <*snip*>
};
#endif

I don't understand why that specific method would cause issues with Sol. All the other methods I've declared work with Sol, and compile fine, but that method throws the error.

If I'm doing something wrong or I need to provide some more information let me so I can get this figured out.

ThePhD commented 8 years ago

Chances are you're not compiling with the define LUA_COMPAT_ALL, which keeps methods like lua_tounsigned available for use (I'm assuming you're using the latest lua, lua 5.3).

Also, if you still have problems after doing -DLUA_COMPAT_ALL, try using the updated version of the library here.

hdt80 commented 8 years ago

Would I put that flag in my compilation command?

ThePhD commented 8 years ago

Yes.

hdt80 commented 8 years ago

I'm at school so I'll rest that when I get can, thanks you for your help.

hdt80 commented 8 years ago

I tried both compilers with -DLUA_COMPACT_ALL, and then using the updated version but I couldn't get either one to work. I'll open an issue in the updated version. Thanks for the help!

ThePhD commented 8 years ago

It's not LUA_COMPACT_ALL, it's LUA_COMPAT_ALL (no C).

hdt80 commented 8 years ago

My apologies, I used -DLUA_COMPAT_ALL, not -DLUA_COMPACT_ALL. I typed it wrong in my Github comment.

hdt80 commented 8 years ago

Looks like using the updated version of the library fixed that, thanks for the help!

douyw commented 7 years ago

In my case, I use lua5.3.4, the macro is LUA_COMPAT_APIINTCASTS.