lua-users home
lua-l archive

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


If I understand correctly what you want to do is to pass an argument to a Lua function by reference. In Lua userdata are held by reference, but you can't modify the reference itself in a function call. So you have to write a constructor that create a userdata with some initial value.

The type of the C objects you're manipulating is :
	typedef root* data_t;
	#define data_0 NULL

I think you should have a C function like that one :
	int CreateNullData(lua_State* L)
	{
		data_t* p = lua_newuserdata(L, sizeof(data_t)); // This pushes a userdata containing a pointer on the stack
		*p = data_0; // Initializes the root* pointer to NULL
		return 1; // Tells lua to use the userdata on the stack as the return value
	}

Your existing function (that you named "function" but I'll call it "foo" for clarity) :
	void c_foo(int x, int y, data_t* p); // I assume the value pointed by p is an in/out parameter since you want to modify it

You bind it to Lua :
	int foo(lua_State* L)
	{
		// Get input parameters
		int x = (int)lua_tonumber(L, 1);
		int y = (int)lua_tonumber(L, 2);
		data_t* p = (data_t*)lua_touserdata(L, 3);
		
		// Call C foo. c_foo may modify the value pointed by p, and this will modify the userdata referenced by the Lua engine.
		c_foo(x, y, p);
		
		return 0;
	}

Then in Lua you do that :
	local x = 0
	local y = 0
	-- Create a null pointer
	local log = CreateNullData()
	-- Call your function foo. Log is not nil, but it points to a userdata containing a null pointer. This pointer can be changed by foo.
	foo(x, y, log)
	-- You can manipulate log as you want.
	-- No new data is created as long as you don't call the constructor again
	-- Here you add a new reference to the same data :
	local log2 = log
	-- and here you remove one :
	log = nil

I hope that helps.

Jérôme.


-----Message d'origine-----
De : lua-bounces@bazar2.conectiva.com.br [mailto:lua-bounces@bazar2.conectiva.com.br] De la part de Lyte _
Envoyé : 19 juillet 2006 03:58
À : lua@bazar2.conectiva.com.br
Objet : Pointers and userdata

Hello!

We are currently working on a project where we are supposed to make certain C-functions available in lua. Just recently we ran into a problem when trying to call a function which requires an address to a pointer as one of the input arguments, such as function(int x, int y, root** p). We have registered it successfully and made it available in lua but the main problem arrises when trying to call this function with a variable created in lua like this:

function(1,2,log)

Now this gives an error according to the underlying implementation since the variable log is null. We would like to call the function with a correct input parameter which would be the "address" to log and not the actual value.

We have currently created a temporary solution to this problem by creating a utility function in C which basically returns the address to a pointer of the correct type.

root** temp() {
   return (root**) &p;
}

If we call temp() from lua and use the return value as an input argument to our other function it returns successfully. We would ofcourse like to avoid this rather dull approach and call the function immediately from lua without first fetching the arguments from C. We have just started learning lua but is there any way of obtaining the address to a variable in lua in or to create userdata immediately in lua?

// Lyte

_________________________________________________________________
Windows Live Messenger är här! http://get.live.com/messenger/overview