I implemented Simple Lua class in C. Usage of class:
require("test")
function foo()
local t1 = test()
local t2 = test()
t1:attach(t2)
return t1
end
o = foo()
-- some code
o = nil
attach function:
int class_attach(lua_State *L)
{
module_data_t *mod = luaL_checkudata(L, 1, "test");
luaL_checktype(L, 2, LUA_TUSERDATA);
module_data_t *child = lua_touserdata(L, 2);
printf("%p->%p\n", (void *)mod, (void *)child);
return 0;
}
After return from function t2 object is cleaned by gc.
Is it possible to prevent that. Set reference between t1 and t2 objects? (calling __gc metamethod (of t2 object) only after parent module (t1) is cleaned).
Simple way is use table:
function foo()
ret = {}
ret[1] = test()
ret[2] = test()
ret[1]:attach(ret[2])
return ret
end
but that is not fun way.
Thanks!
You can set it in the Lua registry. This is effectively a global table which can only be accessed in C code. You can set registry[t1] = t2;. As long as you unset this appropriately in t1's __gc. This can also scale to 1:n mappings, as you could do, for example, registry[t1].insert(t2) for multiple "children".
I've had the same issue in the past. The simple reason for this is that Lua doesn't know about the connection established in C code (there's none right now, but I guess it's going to be done somewhere).
You don't have to do the table approach, just link the two objects/tables/whatever on the Lua side as well:
function foo()
local t1 = test()
local t2 = test()
t1:attach(t2)
t1._dummy_link = t2
return t1
end
Just keep in mind that's only good for 1:1 relationships. For more complex stuff you'll still have to use some kind of table or a similar approach. The probably cleanest way to do this would be doing the linking on the Lua side and just adding a callback to C in case there's C code to be run as well.
Related
I want to create a global interface for a struct instance accessible in Lua. For example, I would create a global instance of a metatable called window as main_window, I would want to then do things like this from Lua:
main_window.color = {1, 2, 3}
main_window.position.x = 64
main_window.show(true)
In an attempt to do this, I used the code from this answer as a base since it's the closest thing I could find. I ended up with an API like this
lua_create_window_type(L);
lua_expose_window(L, main_window);
lua_setglobal(L, "main_window");
...
static int lua_window_index(lua_State* L)
{
struct window_state** w = luaL_checkudata(L, 1, "window");
char* index = luaL_checkstring(L, 2);
if (strcmp(index, "x") == 0) {
lua_pushnumber(L, (*w)->x);
} else if (strcmp(index, "show") == 0) {
lua_pushcfunction(L, lua_window_show);
} else {
...
}
return 1;
}
static int lua_window_newindex(lua_State* L)
{
struct window_state** w = luaL_checkudata(L, 1, "window");
char* index = luaL_checkstring(L, 2);
if (strcmp(index, "x") == 0) {
(*w)->x = luaL_checkinteger(L, 3);
} else {
...
}
return 0;
}
I am inevitably going to end up with tens or hundreds of functions and variables I want to be accessible. Using this template I would have to manually create a if strcmp == 0 else if for every single one. I'd have to duplicate the entire block to allow assignment. I also don't want to end up with functions near the end being comparatively slow to call due to the amount of string comparisons. Overall this does not seem like a "maintainable" solution, nor one the Lua authors would have intended.
When I only needed functions all I had to do was push a standard global table and whatever functions I needed, but trying to allow direct variable access like a native Lua table makes this more difficult (before you ask why not just use functions, I've tried and only having "getter/setter" function access from Lua is very painful and ugly for my uses).
Suggestions for more maintainable alternatives to duplicated if/else blocks?
I'm new to LLVM and would like to create an LLVM pass that performs instrumentation on a c file in the following way:
Say I'm examining the c function lst *add(list* lst, int num) which adds an int to a linked list. I would like to insert some instructions before and after that call, so that I can record the input and output of the function into a file. The recorder is an external tool.
Before instrumentation:
int val = 9;
lst = add(lst, val);
After Instrumentation:
int val = 9;
TypedObject lstObj = {type_lst, lst};
record_input("add", lstObj);
lst = add(lst, val);
TypedObject lstObj = {type_lst, lst};
record_output("add", lstObj);
The record functions receive the type of the TypedObject (Something i use in the recorder tool I've built) and the TypedObject itself.
I have a few questions regarding this procedure:
How can I recognize the specific call to add while iterating through the module? I need to detect a CallInst, and more specifically, one that calls add.
How do I create the instrumented instructions above? I got a little confused with creating instructions.
Thanks a lot to whoever is able to help.
I'm writing an application that uses the wxSQLite3 library, which is a wrapper around libsqlite3 for the wxWidgets cross-platform GUI programming framework. When attempting to reuse a prepared statement, a wxSQLite3Exception is thrown.
This example illustrates the problem:
#include <wx/string.h>
#include <wx/wxsqlite3.h>
int main() {
wxSQLite3Database::InitializeSQLite();
//create in-memory test database & populate it
wxSQLite3Database db;
db.Open(wxT(":memory:"));
db.ExecuteUpdate(wxT("CREATE TABLE SimpleTable (id INT PRIMARY KEY, val INT);"));
db.ExecuteUpdate(wxT("INSERT INTO SimpleTable VALUES (1, 10);"));
db.ExecuteUpdate(wxT("INSERT INTO SimpleTable VALUES (2, 20);"));
//create a prepared statement we can reuse
wxSQLite3Statement stmt;
stmt = db.PrepareStatement(wxT("SELECT * FROM SimpleTable WHERE id = ?;"));
//first use of statement (works)
stmt.Bind(1, 1);
wxSQLite3ResultSet r_set = stmt.ExecuteQuery();
if (r_set.NextRow()) {
wxPrintf(wxT("id: %i value: %i\n"), r_set.GetInt(wxT("id")), r_set.GetInt(wxT("val")));
}
r_set.Finalize();
//reset and reuse statement
stmt.Reset();
stmt.Bind(1, 2); //**EXCEPTION THROWN HERE**
wxSQLite3ResultSet r_set2 = stmt.ExecuteQuery();
if (r_set2.NextRow()) {
wxPrintf(wxT("id: %i value: %i\n"), r_set2.GetInt(wxT("id")), r_set2.GetInt(wxT("val")));
}
r_set2.Finalize();
//cleanup
stmt.Finalize();
db.Close();
wxSQLite3Database::ShutdownSQLite();
return 0;
}
The exception handling was removed for brevity, but the message from the exception is:
WXSQLITE_ERROR[1000]: Statement not accessible
I wrote roughly equivalent code in plain C using libsqlite3 and it ran without problem. Does anyone know what I'm doing wrong, or if this is a bug of some sort in wxSQLite3? Thank you in advance for your help!
In SQLite itself, a statement and a result set actually are the same object.
wxSQLite3 uses reference counting so that the statement is freed only when the last wxSQLite3Statement or wxSQLite3ResultSet object is freed.
This happens automatically in the respective destructors.
However, calling Finalize() explicitly bypasses the reference counting.
While not necessary, if you want to ensure that wxSQLite3ResultSet resources are freed correctly before the next statement execution, just destruct this object:
wxSQLite3Statement stmt = ...;
...
{
wxSQLite3ResultSet r_set = stmt.ExecuteQuery();
... r_set.NextRow() ...
// r_set destructed here
}
...
As long as you intend to reuse a prepared SQL statement, that is, to reset the statement and to bind new values to statement variables, you must not call method Finalize - neither on the prepared statement object itself nor on a result set retrieved from that statement.
As the method name, Finalize, suggests, the method finalizes the underlying SQLite statement object by calling sqlite3_finalize (quotation from the SQLite docs: "The sqlite3_finalize() function is called to delete a prepared statement.") After the underlying SQLite statement object has been deleted, it obviously can't be accessed anymore. Therefore you get the exception.
Usually you don't need to call method Finalize explicitly. wxSQLite3 takes care of finalizing statements through reference counting.
Well there are no problems to push C function as function member or register C function as lua function with lua_register(L, lua_func_name, c_func);
But how tell lua what i want to pass luaFoo() as function callback param for "foober" from C?
lua_pushcfunction - pushes C function, lua_pushstring pushes just a plain string, so callback field became a string, not a function.
Lua Code:
CALLBACKS = {};
FOO = 0;
function luaFoo()
FOO = FOO + 1;
end;
function addCallback(_name, _callback)
CALLBACKS[_name] = _callback;
end;
function doCallback(_name)
CALLBACKS[_name]();
end;
C code:
static int c_foo(lua_State* l)
{
printf("FOO\n");
return 0;
}
/*load lua script*/;
lua_State* l = /*get lua state*/;
lua_getglobal(l, "addCallback");
lua_pushstring(l, "foober");
//What push for luaFoo()
lua_pushcfunction(l, c_foo);
lua_call(l, 2, 0);
lua_getglobal(l, "doCallback");
lua_pushstring(l, "foober");
lua_call(l, 1, 0);
Similiar - if i get C functions which already registered with lua_register, how pass them as callback param from C. So we register c_foo => c_foo exist as lua function, how to tell what we want to pass "c_foo" as callback func param.
Remember that:
function luaFoo()
...
end
is equivalent to this, in Lua:
luaFoo = function()
...
end
Therefore, your question ultimately boils down to, "I have a value in the global table. How do I push it onto the stack?" The fact that this value is a function is irrelevant; a function value in Lua is no different from an integer value, which is no different than a string value. Obviously you can do different things with them, but you just want to copy them around. That works the same regardless of what the value is.
The function you're looking for is lua_getglobal.
As for your second question, you can do it in one of two ways. You can either get the function value you registered from the global table, or you can simply re-register it with lua_pushcfunction. Since you're not using upvalues, re-registering it doesn't really have any downsides.
Oh, and one more thing, on code style. Lua doesn't require ; at the end of statements. You can do it (to make C-native programmers feel more comfortable), but it's not necessary.
I want to update the Volume to each #IP. So that for example after each 5 s I add V(i) of each #IP(i). Ok Now the hash table works fine it keeps updated after every T seconds. But the problem is that after a certain period I find that sometimes the same ip adress is repeated twice or even a lot of times within the hash table. So that when I close the process I find the same #IP repeated too many times. It is like there is a problem with the hash table or something like that.
Here is the code this funcion "update_hashTable()" is so important it is called every X seconds I suspect in fact a memory leak ... because I always call malloc for IP#.
but it keeps working ... any idea ???
int update_hashTable( ... ) {
u_int32_t *a;
... //declarations
struct pf_addr *as;
as = ks->addr[0];
a = (u_int32_t*)malloc(sizeof(u_int32_t));
*a = ntohl(as->addr32[0]);
sz = value; // no matter it is... an int for example
if (ReturnValue=(u_int32_t)g_hash_table_lookup(hashtable, a)) {
ReturnValue +=sz;
g_hash_table_insert(hashtable, (gpointer)a, gpointer)ReturnValue);
}
else {
g_hash_table_insert(hashtable, (gpointer)a, (gpointer)sz);
}
Indeed, you appear to have a memory leak, but this isn't your problem. The problem is that the true-path of your if statement simply reinserts a second value associated with the same key, which is not what you want.
The typical pattern for this check-if-exists and increment algorithm is usually something like
gpointer val = g_hash_table_lookup(hash_table, key);
if (val == NULL) {
val = g_malloc0(...);
g_hash_table_insert(hash_table, key, val);
}
*val = /* something */;
The important thing to take away from this is that once you have a pointer to the value associated with some key, you can simply modify it directly.
If this code will be executed by multiple threads in parallel, then the entire block should be protected by a mutex, perhaps with GMutex: http://developer.gnome.org/glib/2.28/glib-Threads.html
gcc provides atomic builtin intrinsics, say for atomically incrementing the value, see http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html