lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hello,

I know it's christmas time and not halloween anymore but ...

look, please:

What do you think about a dynamic library, called by lua, which hang when calling an inside function with a certain name ? This library works as stand alone executable, and when used with C another C program.

More details:

This function is called by Lua:


int lua_step(lua_State *L)
{
  int tex_id = (int)lua_tointeger(L, -1);
  gl_logo_texture_id = tex_id;

  step();

  lua_pushboolean(L, esc_pressed);
  return 1;
}


It hangs on step() (which is internal function of the library, no relation with lua script), which is called by "lua_step()". When i change the name of function "step()" , let's say "foo_step()", it works.

Now, i see you coming : "it's certainly a problem with a "step" function unrelated, but called in your library." Except that this library can be build as a stand-alone executable, and it works. It works also when used as a library with a C program (so i think this problem is related with Lua, but i don't know why).

Here is a shortened sample of my problem, but with the same behaviour. I know it's a bit long, but i did what i could.

I will be grateful if someone can at least test on his machine. I did the test on two differents PC, with same problem. (discomment "foo_step()" call, and comment "step()" call in "lua_step()" function for running the library without errors, when called by lua script).


//for lib build:
//gcc gl_debug.c -fPIC -shared -ggdb -o gl_debug.so -lglut -lGLU -llua -Wall -W

//standalone executable:
// gcc gl_debug.c -ggdb -o gl_debug.elf -lglut -lGLU -llua -Wall -W -DBUILD_EXE


#include <stdio.h>
#include <unistd.h>
#include <GL/gl.h>
#include <GL/freeglut.h>


#include <lua.h>
#include <lauxlib.h>

int gl_logo_texture_id = 0;

int esc_pressed = 0;

typedef struct { float x; float y; float z; } Coords3d;
Coords3d orbite = {0,0,0};


int draw_cube ()
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Screen & Depth Buffer

  Coords3d eye={0,0,2}, center={0,0,0};
  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();
  gluLookAt(eye.x,eye.y,eye.z ,
        center.x,center.y,center.z,
        0,1,0
        );

  glRotatef(orbite.x+=.2,1,0,0);
  glRotatef(orbite.z+=.1 ,0.,0., 1.);

  glutWireCube(1);

  return 0;
}



void lua_display_cb(lua_State *L_init)
{
  static lua_State *L = 0;
  static int index_fx_disp = LUA_REFNIL;

  if (L_init) {
    /* called by "init" function of the C library */
    L = L_init;
    lua_getfield (L,LUA_GLOBALSINDEX,"lua_display_fx");
    index_fx_disp = luaL_ref (L, LUA_REGISTRYINDEX);
    if (index_fx_disp == LUA_REFNIL) {
      fprintf(stderr,"luaL_ref : erreur\n");
    }

  } else {
    /* called by lua function "lua_display_fx" */
    lua_rawgeti (L, LUA_REGISTRYINDEX, index_fx_disp);
    lua_pcall(L, 0,0,0);
  }

}


void display (void)
{
  draw_cube(0);
  glutSwapBuffers();
}

void lua_display (void)
{
  lua_display_cb(0);
  glutSwapBuffers();
}

void reshape ( int w, int h )
{
  glViewport     ( 0, 0, w, h );
  glMatrixMode   ( GL_PROJECTION );
  glLoadIdentity ( );
  if ( h==0 )  // Calculate The Aspect Ratio Of The Window
     gluPerspective ( 80, ( float ) w, 1.0, 5000.0 );
  else
     gluPerspective ( 80, ( float ) w / ( float ) h, 1.0, 5000.0 );
  glMatrixMode   ( GL_MODELVIEW );
  glLoadIdentity ( );
}


void keyboard ( unsigned char key, int x, int y ) // Create Keyboard Function
{
  x=x; y=y;
  switch ( key ) {
    case 27:        // escape
      esc_pressed = 1;
      break;

    default:
      break;
  }
}


static void timerCallback(int id_timer)
{
  glutPostRedisplay();
  glutTimerFunc(20, timerCallback, id_timer);
}



void init ( GLvoid )     // Create Some Everyday Functions
{
  int argc=1; char *argv[]= {"init", 0 }; //nécessaire pour glutInit
  glutInit   (&argc, argv); // ( &argc, argv );

  glClearColor (0.3f, 0.5f, 0.8f, 1.0f);
  glEnable(GL_NORMALIZE);
  glShadeModel (GL_SMOOTH);
  glEnable (GL_DEPTH_TEST);


  glutInitDisplayMode ( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
  glutInitWindowSize  ( 500, 500 );
  glutCreateWindow    ( "OpenGL Framework" );

  glutDisplayFunc     ( display );
  glutReshapeFunc     ( reshape );
  glutKeyboardFunc    ( keyboard );

  glutTimerFunc (20, timerCallback, 1);
}


int lua_init(lua_State *L)
{
  lua_display_cb(L); //initialise with context of calling script
  init();
  return 0;
}


void step()
{
  glutMainLoopEvent();
  usleep(1);
}

void foo_step()
{
  glutMainLoopEvent();
  usleep(1);
}


int lua_step(lua_State *L)
{
  int tex_id = (int)lua_tointeger(L, -1);
  gl_logo_texture_id = tex_id;

//  foo_step(); //doesn't hang
  step(); //hangs (doh!)

  lua_pushboolean(L, esc_pressed);
  return 1;
}


#ifdef BUILD_EXE
int main ( int argc, char** argv )
{
  argc=argc;
  argv=argv;
  init ();
  while (!esc_pressed) {
    step();
  }
  return 0;
}
#endif


=====
Now the lua script for calling the library:

#!/usr/bin/env lua

function loadfx (dll, fxname)
   fx,err = package.loadlib(dll, fxname)
   if not fx then
      print (err)
   end

   return fx
end

-- called by the glut render loop
function lua_display_fx()
   t_fx.draw_cube(tex_id)
end


t_fx = { lua_init=0, lua_step=0 , draw_cube=0 }

for k,v in pairs(t_fx) do
t_fx["k"]
   t_fx[k] = loadfx ("./gl_debug.so", k)
end

t_fx.lua_init()

tex_id=0
repeat
 esc_pressed = t_fx.lua_step(tex_id)
until esc_pressed

print ("end")