patterncMinor
Tiny Lua library to get char pointer from string
Viewed 0 times
chartinypointergetlibraryfromstringlua
Problem
Background
I'm using Lua with luaglut to do some OpenGL stuff. The luaglut API is almost identical to the gl/glut C APIs. Sometimes, gl functions want a pointer to some data, for example:
In these cases, the luaglut bindings take a light userdata containing the pointer. In the luaglut demos, a small example library called memarray does the work of setting up a C array and returning a pointer to it as a light userdata.
You might use "memarray" something like this:
That got me thinking, why do we need memarray at all? Lua strings should be binary safe; all we really need is to get a pointer to the string returned from
Of course we pass the string around instead of the pointer, because the GC could free the memory the string was in if there are no more references to it, invalidating the pointer. Internally Lua strings are immutable and passed by reference anyway, so this is no big deal.
Code
`#include
#include
#include
int get_pointer(lua_State *L)
{
luaL_checktype(L, 1, LUA_TSTRING);
lua_pushlightuserdata(L, (void *)lua_tostring(L
I'm using Lua with luaglut to do some OpenGL stuff. The luaglut API is almost identical to the gl/glut C APIs. Sometimes, gl functions want a pointer to some data, for example:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, oh_crap_a_pointer)
In these cases, the luaglut bindings take a light userdata containing the pointer. In the luaglut demos, a small example library called memarray does the work of setting up a C array and returning a pointer to it as a light userdata.
You might use "memarray" something like this:
require 'memarray'
function loadTexture(filename)
local file = assert(io.open(filename, 'rb'))
local data = file:read('*a')
file:close()
local array = memarray('uchar', #data)
array:from_str(data)
return array
end
-- ... later
local texture = loadTexture('whatever.rgba')
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA,
GL_UNSIGNED_BYTE, texture:ptr())
That got me thinking, why do we need memarray at all? Lua strings should be binary safe; all we really need is to get a pointer to the string returned from
file:read('*a') as a light userdata. It would look something like this:function loadTexture(filename)
local file = assert(io.open(filename, 'rb'))
local data = file:read('*a')
file:close()
return data
end
-- ... later
local stringpointer = require 'stringpointer'
local texture = loadTexture('whatever.rgba')
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA,
GL_UNSIGNED_BYTE, stringpointer.get(texture))
Of course we pass the string around instead of the pointer, because the GC could free the memory the string was in if there are no more references to it, invalidating the pointer. Internally Lua strings are immutable and passed by reference anyway, so this is no big deal.
Code
`#include
#include
#include
int get_pointer(lua_State *L)
{
luaL_checktype(L, 1, LUA_TSTRING);
lua_pushlightuserdata(L, (void *)lua_tostring(L
Solution
I'm no Lua expert, but I can at least give you a pointer (no pun intended) about your C code.
Your
Your
get_pointer function looks like it works fine, but it could be made even more concise! Lua provides a luaL_checkstring function that combines luaL_checktype and luaL_tostring. Therefore, you could just do this:int get_pointer(lua_State *L)
{
lua_pushlightuserdata(L, (void *) luaL_checkstring(L, 1));
return 1;
}Code Snippets
int get_pointer(lua_State *L)
{
lua_pushlightuserdata(L, (void *) luaL_checkstring(L, 1));
return 1;
}Context
StackExchange Code Review Q#62059, answer score: 6
Revisions (0)
No revisions yet.