Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] [SFML] [LUA] Funkcja zawarta w klasie nie nadpisuje jej składowej

Ostatnio zmodyfikowano 2015-12-27 19:32
Autor Wiadomość
Gibas11
Temat założony przez niniejszego użytkownika
[C++] [SFML] [LUA] Funkcja zawarta w klasie nie nadpisuje jej składowej
» 2015-12-27 17:47:44
Witam, funkcja
int luaVirtualMachine::api_read( lua_State * L )
 wywoływana jest przez skrypt lua z innego wątku, z nieznanego mi powodu mimo ustawienia zmiennej „_reguiresData” zmienna ta zachowuje poprzednią wartość. Próbowałem ustawić zmienną na
volatile
 i wyłączyć optymalizacje - bez efektu

C/C++
#include <SFML/System.hpp>
#include <iostream>
#include <queue>
#include <cstring>
#include <string>

using namespace std;

extern "C" {
    #include "lua5.2/lua.h"
    #include "lua5.2/lualib.h"
    #include "lua5.2/lauxlib.h"
}

class luaVirtualMachine
{
private:
    string output;
    string input;
   
    sf::Thread luaScript;
    lua_State * state;
    char * _file;
   
    void execute();
   
    bool ready;
    bool running;
   
    bool _reguiresData;
   
    int api_read( lua_State * L );
    int api_write( lua_State * L );
public:
    luaVirtualMachine();
    luaVirtualMachine( const char * file );
    ~luaVirtualMachine();
   
    bool open( const char * file );
    bool close();
    bool launch();
   
    bool isRunning();
    bool reguiresData();
   
    void putstring( string c );
    string getstring();
   
};

void luaVirtualMachine::execute()
{
    luaL_dofile( state, _file );
    running = false;
}

int luaVirtualMachine::api_read( lua_State * L )
{
    _reguiresData = true;
    cout << _reguiresData << endl; //<- Tutaj wyświetla '1'
    for(;; )
    {
        if( !reguiresData() )
        {
            lua_pushstring( L, input.c_str() );
            break;
        }
        cout.flush();
    }
    return 1;
}

luaVirtualMachine::luaVirtualMachine()
    : luaScript( & luaVirtualMachine::execute, this )
{
    ready = false;
    running = false;
    _reguiresData = false;
}
luaVirtualMachine::luaVirtualMachine( const char * file )
    : luaScript( & luaVirtualMachine::execute, this )
{
    open( file );
    running = false;
    _reguiresData = false;
}
luaVirtualMachine::~luaVirtualMachine()
{
    close();
}

bool luaVirtualMachine::open( const char * file )
{
    if( ready )
         return false;
   
    state = luaL_newstate();
    luaL_openlibs( state );
   
    lua_register( state, "read",( lua_CFunction ) & luaVirtualMachine::api_read );
    //lua_register(state, "write", (lua_CFunction) &luaVirtualMachine::api_write); {TO DO}
   
    _file = new char[ strlen( file ) + 1 ];
    strcpy( _file, file );
   
    ready = true;
    return true;
}
bool luaVirtualMachine::close()
{
    if( !ready )
         return false;
   
    lua_close( state );
    ready = false;
    delete _file;
    return true;
}
bool luaVirtualMachine::launch()
{
    if( !ready )
         return false;
   
    running = true;
    luaScript.launch();
    return true;
}

bool luaVirtualMachine::isRunning()
{
    return running;
}
bool luaVirtualMachine::reguiresData()
{
    return _reguiresData;
}

void luaVirtualMachine::putstring( string s )
{
    input = s;
    _reguiresData = false;
}
string luaVirtualMachine::getstring()
{
    return output;
}

int main()
{
    luaVirtualMachine lvm1( "example.lua" );
   
    lvm1.launch();
    while( lvm1.isRunning() )
    {
        cout << lvm1.reguiresData(); //<- Same zera, mimo że po chwili powinno zacząć wyświetlać "1".
        if( lvm1.reguiresData() )
        {
            string str;
            cin >> str;
            lvm1.putstring( str );
        }
    }
   
    return 0;
}
EDIT: Poprawiłem literówkę.
P-142417
1aam2am1
» 2015-12-27 18:11:26
Linijkę wyżej zmieniasz ją na true
P-142419
Gibas11
Temat założony przez niniejszego użytkownika
» 2015-12-27 18:17:07
No właśnie, a tak jak mówiłem w innym wątku (11 linia od dołu) wyświetla mi, że dalej jest równa
0
, w tym problem.
P-142420
Monika90
» 2015-12-27 18:39:27
Taka zmienna powinna być atomowa: std::atomic<bool>.


C/C++
lua_register( state, "read",( lua_CFunction ) & luaVirtualMachine::api_read );
To jest prawdopodobnie błędne.
P-142421
Gibas11
Temat założony przez niniejszego użytkownika
» 2015-12-27 19:00:38
Mimo ustawienia typu na
atomic < bool >
 nic się nie zmieniło. Co do rzutowania tego wskaźnika to wyglądało mi to dziwnie ale działa. (testowałem - funkcja jest poprawnie wywoływana)

Zamieszczam jeszcze raz kod, z kilkoma drobnymi zmianami. (Włącznie z
atomic < bool >
)
C/C++
#include <SFML/System.hpp>
#include <iostream>
#include <cstring>
#include <string>
#include <atomic>

using namespace std;

extern "C" {
    #include "lua5.2/lua.h"
    #include "lua5.2/lualib.h"
    #include "lua5.2/lauxlib.h"
}

class luaVirtualMachine
{
private:
    string output;
    string input;
   
    sf::Thread luaScript;
    lua_State * state;
    char * _file;
   
    void execute();
   
    bool ready;
    bool running;
   
    atomic < bool > _reguiresData;
   
    int api_read( lua_State * L );
    int api_write( lua_State * L );
public:
    luaVirtualMachine();
    luaVirtualMachine( const char * file );
    ~luaVirtualMachine();
   
    bool open( const char * file );
    bool close();
    bool launch();
   
    bool isRunning();
    bool reguiresData();
    void reguiresData( bool opt );
   
    void putstring( string c );
    string getstring();
   
};

void luaVirtualMachine::execute()
{
    luaL_dofile( state, _file );
    running = false;
}

int luaVirtualMachine::api_read( lua_State * L )
{
    reguiresData( true );
    for(;; )
    {
        if( !reguiresData() )
        {
            lua_pushstring( L, input.c_str() );
            break;
        }
        cout.flush();
    }
    return 1;
}

luaVirtualMachine::luaVirtualMachine()
    : luaScript( & luaVirtualMachine::execute, this )
{
    ready = false;
    running = false;
    reguiresData( false );
}
luaVirtualMachine::luaVirtualMachine( const char * file )
    : luaScript( & luaVirtualMachine::execute, this )
{
    ready = false;
    open( file );
    running = false;
    reguiresData( false );
}
luaVirtualMachine::~luaVirtualMachine()
{
    close();
}

bool luaVirtualMachine::open( const char * file )
{
    if( ready )
         return false;
   
    state = luaL_newstate();
    luaL_openlibs( state );
   
    lua_register( state, "read",( lua_CFunction ) & luaVirtualMachine::api_read );
    //lua_register(state, "write", (lua_CFunction) &luaVirtualMachine::api_write); {TO DO}
   
    _file = new char[ strlen( file ) + 1 ];
    strcpy( _file, file );
   
    ready = true;
    return true;
}
bool luaVirtualMachine::close()
{
    if( !ready )
         return false;
   
    lua_close( state );
    ready = false;
    delete _file;
    return true;
}
bool luaVirtualMachine::launch()
{
    if( !ready )
         return false;
   
    running = true;
    luaScript.launch();
    return true;
}

bool luaVirtualMachine::isRunning()
{
    return running;
}
bool luaVirtualMachine::reguiresData()
{
    return _reguiresData;
}
void luaVirtualMachine::reguiresData( bool opt )
{
    _reguiresData = opt;
}

void luaVirtualMachine::putstring( string s )
{
    input = s;
    reguiresData( false );
}
string luaVirtualMachine::getstring()
{
    return output;
}

int main()
{
    luaVirtualMachine lvm1( "example.lua" );
   
    lvm1.launch();
    while( lvm1.isRunning() )
    {
        if( lvm1.reguiresData() )
        {
            string str;
            cin >> str;
            lvm1.putstring( str );
        }
    }
   
    return 0;
}
P-142422
Monika90
» 2015-12-27 19:05:01
C/C++
std::cout << this << std::endl;
Dodaj tę linijkę w funkcji api_read oraz w konstruktorze klasy i porównaj wyświetlone adresy.
P-142423
Gibas11
Temat założony przez niniejszego użytkownika
» 2015-12-27 19:08:40
Ups, inne. :< Albo lua robi coś co mi się nie podoba tutaj:
lua_register( state, "read",( lua_CFunction ) & luaVirtualMachine::api_read );
. albo nie mam chwilowo żadnego pomysłu.
EDIT: Wydaje mi się, czy adres z konstruktora ma 64 bity a z funkcji 32?
P-142424
Monika90
» 2015-12-27 19:20:33
EDIT: Wydaje mi się, czy adres z konstruktora ma 64 bity a z funkcji 32?
Nie.

Lua oczekuje wskaźnika do zwykłej funkcji, a nie funkcji składowej. To są różne typy funkcji, niestatyczne funkcje składowe mają ukryty parametr, czyli wskaźnik this. Interpreter tego parametru nie przekazuje. Skąd w ogóle miałby wiedzieć pod jakim adresem znajduje się Twój obiekt?


Wywoływanie niestatycznych funkcji składowych z Lua wydaje się być skomplikowane, zobacz np. tutaj https://bitbucket.org/alexames​/luawrapper/src
P-142425
« 1 » 2
  Strona 1 z 2 Następna strona