I don't really want to go down the metatables etc. route as it seems rather complicated.
To crudely access 'C' structs in Lua I do:
void execute_lua_script(char *name)
{
lua_pushstring (L,name);
lua_gettable (L, LUA_GLOBALSINDEX);
lua_pushstring(L,"junk");
lua_pushinteger(L,7);
lua_pushlightuserdata(L, avatar_obj);
lua_pcall (L, 3, 2, 0);
}
The registered C func is:
int get_obj_struct(lua_State *L)
{
const char *str;
OBJECT_DEF *obj;
int stack;
obj=(OBJECT_DEF *)lua_touserdata(L,1);
str=lua_tostring(L,2);
//printf("\nIN OBJ:%d %s",obj,str);
if (!strcmp(str,"body->p.x"))
lua_pushnumber(L,obj->body->p.x);
if (!strcmp(str,"collided_with"))
lua_pushlightuserdata(L, obj->collided_with);
if (!strcmp(str,"type"))
lua_pushnumber(L,obj->type);
stack=lua_gettop(L);
//printf("\n%d",stack);
if (stack<3)
report_error("Unknown structure request ",(char *)str);
return 1;
}
Although crude; it works! :-)
The problem is when I request "collided_with" (a pointer); I need to return that back to my script; but for reasons I don't understand 'obj' ends up as nil.
My lua script:
function test(a,b,obj)
--print("\nLUA! test:",a,b);
b=b+1;
c=get_obj_struct(obj,"body->p.x");
--print("x:",c);
collided_with=get_obj_struct(obj,"collided_with");
type=get_obj_struct(collided_with,"type");
print("type:",type);
return a,b;
end
I am expecting 'collided_with' to be a pointer that I can then pass back into get_obj_struct and look for type.
I know it's something to do with me mis-using pushlightuserdata and also reading for the obj.
So an explanation would be great!. Also if someone wishes to give a version that uses 'tables' (as I assume that would be much more efficient) then I would be grateful for the help.
The online "Programming In Lua" book provides a good description of how to implement Lua types in C. In my opinion, your best bet would be to follow the examples provided in Chapter 28 to "do it right" and create a complete Lua wrapper for your object. In addition to being easier to maintain, it will almost certainly be more faster than a strcmp based implementation.
Related
Consider the following line of code that doesn't compile in Dart -- lack of comma operator, but comparable things are totally fine in JavaScript or C++:
final foo = (ArgumentError.checkNotNull(value), value) * 2;
The closest I could get with an ugly workaround is
final foo = last(ArgumentError.checkNotNull(value), value) * 2;
with function
T last<T>(void op, T ret) => ret;
Is there a better solution?
Dart does not have a comma operator similar to the one in JavaScript.
There is no obviously better solution than what you already have.
The work-around operation you introduced is how I would solve it. I usually call it seq for "sequence" if I write it.
There is sadly no good way to use an extension operator because you need to be generic on the second operand and operators cannot be generic. You could use an extension method like:
extension Seq on void {
T seq<T>(T next) => next;
}
Then you can write ArgumentError.checkNotNull(value).seq(value).
(For what it's worth, the ArgumentError.checkNotNull function has been changed to return its value, but that change was made after releasing Dart 2.7, so it will only be available in the next release after that).
If the overhead doesn't matter, you can use closures without arguments for a similar effect (and also more complex operations than just a sequence of expressions).
final foo = () {
ArgumentError.checkNotNull(value);
return value;
} ();
This is not great for hot paths due to the overhead incurred by creating and calling a closure, but can work reasonably well outside those.
If you need this kind of test-plus-initialization pattern more than once, the cleanest way would arguably be to put it in a function of its own, anyway.
T ensureNotNull<T>(T value) {
ArgumentError.checkNotNull(value);
return value;
}
final foo = ensureNotNull(value);
I'm writing a Lua library which registers some metatables using luaL_newmetatable(). Since other libraries might do that as well, I'd like to ask what is a good strategy to avoid having the same name used twice. I was thinking about using a reverse DNS name like com.mydomain.mylibrary which should be pretty safe I guess. However, I'd like to ask if there maybe is a better or standard way of choosing unique names for libraries using luaL_newmetatable().
I like use lightuserdata with pointer to string.
#define LCURL_EASY_NAME LCURL_PREFIX" Easy"
static const char *LCURL_EASY = LCURL_EASY_NAME;
It just requires simple functions to use it.
int lutil_newmetatablep (lua_State *L, const void *p) {
lua_rawgetp(L, LUA_REGISTRYINDEX, p);
if (!lua_isnil(L, -1))
return 0;
lua_pop(L, 1);
lua_newtable(L); /* create metatable */
lua_pushvalue(L, -1); /* duplicate metatable to set*/
lua_rawsetp(L, LUA_REGISTRYINDEX, p);
return 1;
}
Similar for get/set. Checkout e.g. my Lua-cURL library.
I would use a string that describes what is in the "object" as this string is output in Lua error message eventually:
e.g. if the metatable is named "database connection":
stdin:1: bad argument #1 to 'status' (database connection expected, got no value)
If you use a UUID, nobody can make sense of the output.
I've got a structure with C representation:
struct Scard_IO_Request {
proto: u32,
pciLength: u32
}
when I want to ask the sizeof (like in C sizeof()) using:
mem::sizeof<Scard_IO_Request>();
I get compilation error:
"error: `sizeof` is a reserved keyword"
Why can't I use this sizeof function like in C? Is there an alternative?
For two reasons:
There is no such function as "sizeof", so the compiler is going to have a rather difficult time calling it.
That's not how you invoke generic functions.
If you check the documentation for mem::size_of (which you can find even if you search for "sizeof"), you will see that it includes a runnable example which shows you how to call it. For posterity, the example in question is:
fn main() {
use std::mem;
assert_eq!(4, mem::size_of::<i32>());
}
In your specific case, you'd get the size of that structure using
mem::size_of::<Scard_IO_Request>()
Lets say I have an IDL function:
void foo(out Data d);
When I inherit from the generated code the signature will look sth like this:
void foo(IDL::Data_out d);
My first question is, what do I have to pass on the client side? I tried:
IDL::Data_out d;
_servantRef->foo(d);
but this doesn't work because Data_out doesn't have a default constructor. I then tried:
IDL::Data* d;
_servantRef->foo(d);
but now the compiler can't cast from IDL::Data* to IDL::Data_out. The following works but looks overcomplicated and thus not correct:
IDL::Data* d(NULL);
IDL::Data_out do(d);
_servantRef->foo(do);
How do I have to proceed from there? During its execution of foo() the servant will at some point allocate a data object like this:
void Servant::foo(IDL::Data_out d)
{
d = new Data();
}
I will then delete the object after having used it on the client side like this:
IDL::Data* d(NULL);
IDL::Data_out do(d);
_servantRef->foo(do);
delete d;
Is this at least correct by its idea or does this work differently? Would appreciate a little help or pointers to documentation where this is described in a understandable way.
You have to use the _var classes correctly, they are like an auto_ptr and make sure the memory is freed when the _var goes out of scope. The client code should be
IDL::Data_var d;
_servantRef->foo (d.out ());
The servant code should be
void Servant::foo(IDL::Data_out d)
{
d = new Data();
}
The new IDL to C++11 language mapping makes this way easier, there the client code is
IDL::Data d;
_servantRef->foo (d);
The servant code is
void Servant::foo(IDL::Data& d)
{
// modify d
}
See TAOX11 for more details about IDL to C++11.
Johnny Willemsen's answer is good. But you also asked:
Would appreciate a little help or pointers to documentation where this is described in a understandable way.
See the book Advanced CORBA Programming with C++ by Henning & Vinoski.
You can also download a copy of the official IDL to C++ language mapping document here. The IDL to C++11 language mapping is available here.
I want users of my C++ application to be able to provide anonymous functions to perform small chunks of work.
Small fragments like this would be ideal.
function(arg) return arg*5 end
Now I'd like to be able to write something as simple as this for my C code,
// Push the function onto the lua stack
lua_xxx(L, "function(arg) return arg*5 end" )
// Store it away for later
int reg_index = luaL_ref(L, LUA_REGISTRY_INDEX);
However I dont think lua_loadstring will do "the right thing".
Am I left with what feels to me like a horrible hack?
void push_lua_function_from_string( lua_State * L, std::string code )
{
// Wrap our string so that we can get something useful for luaL_loadstring
std::string wrapped_code = "return "+code;
luaL_loadstring(L, wrapped_code.c_str());
lua_pcall( L, 0, 1, 0 );
}
push_lua_function_from_string(L, "function(arg) return arg*5 end" );
int reg_index = luaL_ref(L, LUA_REGISTRY_INDEX);
Is there a better solution?
If you need access to parameters, the way you have written is correct. lua_loadstring returns a function that represents the chunk/code you are compiling. If you want to actually get a function back from the code, you have to return it. I also do this (in Lua) for little "expression evaluators", and I don't consider it a "horrible hack" :)
If you only need some callbacks, without any parameters, you can directly write the code and use the function returned by lua_tostring. You can even pass parameters to this chunk, it will be accessible as the ... expression. Then you can get the parameters as:
local arg1, arg2 = ...
-- rest of code
You decide what is better for you - "ugly code" inside your library codebase, or "ugly code" in your Lua functions.
Have a look at my ae. It caches functions from expressions so you can simply say ae_eval("a*x^2+b*x+c") and it'll only compile it once.