I would like to know is there a way to pass a struct pointer to a lua script,
and reach it's members from lua without copy (for read and write purposes).
So, for example is it possible to overwrite a member of a c struct directly through of its pointer?
(I am using luajit)
In addition to Tim's answer, you can also go for light userdata. You don't end up with a copy of your data in the Lua stack, all you push to Lua is a pointer.
Lua has no understanding of what is in this pointer, whether it still points to valid memory, or how to access any objects in this pointer, so you'll have to handle all of this yourself in C. I am usually sending a pointer to an item on a list, so if there's any risk that entry has been deleted from the list, I first iterate over the list to validate the pointer (not a big deal if your lists are short). To access items within the pointer in Lua, you need to write get/set functions in C that you can call from Lua.
To get started, here are the entries on pushing and retrieving the lightuserdata:
lua_pushlightuserdata - push an entry on the stack
lua_touserdata - retrieve the pointer value
lua_islightuserdata - validate entry is light userdata
Programming in Lua entry on light userdata
Seeing as you have tagged this for luajit, you can combine the light userdata (as mentioned by others) with FFI for direct struct member access, see the tutorial here: http://luajit.org/ext_ffi_tutorial.html
The way to do this is with a lua userdata. Here are a couple examples: link, another link.
Related
Say I have a lua object created with io.open/io.popen. is there a way to bind a C structure to it by calling some c defined function from lua that takes the (io.open/io.popen)-ed object as an argument and binds a newly allocated struct to it?
the purpose of wanting to do this is so I can hopefully keep that newly allocated structure around until the lua object gets closed or garbage collected and have that free the C structure automatically at that point.
I've been reading on metamethods but I'm not sure I want to overwrite the default object behavior (maybe just add an extra function?) or if that's even the right approach to achieve the above.
Any help/hint on how to achieve this would be greatly appreciated!
Hello i am trying to learn and build data structures in c and i want to store integers progressively in the stack.
my struct is like this:
typedef struct STACK_NODE_s *STACK_NODE;
typedef struct STACK_NODE_s{
STACK_NODE forward;
void *storage;
} STACK_NODE_t;
typedef struct L_STACK_s{
STACK_NODE top;
} L_STACK_t, *L_STACK;
In a while loop i want to read and store my chars in integer form.
//assume that str is an proper string
//assume that we have a linked stack called LS
int i=0;
int temp;
while(str[i]!='\0'){
tmp=str[i]-'0';
push(LS,(void *)&tmp);
}
I know this won't work properly as we store the same variable's adress over and over again.
Do i need to allocate an auxiliary array in order to store them 1 by 1 or is there a better way to do this?
The answer must address two separate aspects of your question:
How to organize some collection of items, and where to get the memory from to do that.
First code snippet / Linked list format
The first code snippet is good the way it is.
It sets up a linked list, which has its pros and cons, but serves very well if you don't know the number of items in advance, if you want to be able to quickly remove or insert items somewhere in the middle of the list, and if you don't mind that looking up one certain entry inside the list costs you O(N) effort.
For a generic library-like implementation...
... void* is as good as it goes with ANSI C.
In C++, for example, you could make a template that leaves open the type that is stored in the list (or better yet, you would directly reuse the well-known STL implementation in class forward_list<int>).
Sadly, ANSI C doesn't have something comparable.
One solution is the one you picked, create int objects and hook their addresses into your list of void*.
Another solution for a generic library implementation is to use a precompiler macro for the type, and to define this macro above a header file that holds the generic implementation. This tries to resemble the clean C++ solution, but with precompiler it is not typesafe, so this approach is far from beautiful and comes with several risks.
Second code snippet / Memory allocation
Creating the list with void* instead of int (or whatever non-pointer type) requires you to allocate further memory beside the list.
I. e., it is not only that you have to allocate every list item (= variable of type STACK_NODE_t) but also the actual entry value (e. g., *(int*)(LS->storage)).
This means you have to allocate/deallocate the data in some other way that outlives the stack.
On most systems, you can use malloc/free for that, and you only have to take into account the size of the heap available for malloc and the time de-/allocating takes.
If the list shall implement real-time requirements or on embedded systems, you may not have malloc or you may not be allowed to use it.
Then you have to allocate and implement your own heap (= memory pool of storage items) for your list.
How to implement such a memory pool with desired properties is a separate question that would take us to far here.
In any case, you must not use the pointer to a stack variable (like a local variable inside a function) because the memory "behind" that variable will not be reserved for this purpose once the function exits, and the memory may be used for something different in the meantime.
This is, however, what the second code snippet does apparently.
As you noticed yourself, taking this path...
we store the same variable's adress over and over again.
Reusing the memory position for another entry of the same list is an extreme case of the risk explained above.
I solved the problem using an auxiliary array like i anticipated. If someone comes up with a better solution its more than welcome.
(Context: The system I am working on already maintains a form of garbage collection. I'm working on compaction.)
Most compaction algorithms follow a basic structure:
Find first object
Move object to beginning of heap
Find second object
Move second object to address right after first object
Rinse and repeat
This algorithm is followed in section 2.2 of this paper except using two pointers, denoted "from" and "to". Essentially the FROM pointer traverses the heap until it finds live objects. Then it moves said object to the TO pointer. Then TO is incremented accordingly.
The algorithm is simple, but I have yet to find much information on how these pointers determine what is a "live object". This article discusses the creation of a basic mark-and-sweep garbage collector that runs through the stack, recursively going to each reference and marking them as live. The article however requires a linked list of ALL objects ever allocated. However, this is because the author is more or less creating their own VM.
My question is, is there a way of traversing a heap in C and identifying whether the current object is a live object? Is there a similar linked list of all allocated objects already in C that I could use? Or will I require more overhead?
My question is, is there a way of traversing a heap in C and identifying whether the current object is a live object?
At a high level, the process is looking at all active pointers and determining whether or not each piece of allocated memory is accessible. (Please note that this is very complicated is C, including because a pointer could be stored in an int or other data types.) If the memory is accessible via a pointer, then it is "live" in your terms. If not, then garbage collectors would consider it safe to free that memory.
If you're asking whether or not C has a native function for determining whether or not some allocated memory can be reached, then the answer is no.
Is there a similar linked list of all allocated objects already in C that I could use? Or will I require more overhead?
Again, if you're looking for a linked list that C natively provides and you can access, then the answer is no. You'd need to implement these things.
Forgive me if you've already seen this, but there are garbage collectors that you can download if you want to see how others have done it.
TL;DR: It's impossible.
To make that work, you need to solve some non-trivial problems:
Be able to name the live objects of the heap. That means to find and follow recursively all pointers in global variables and on the stack.
Move the live objects downwards to create a compact heap
Adjust pointers in your program to reflect the new locations of the moved objects.
Regarding 1.: At runtime, the C language doesn't help you to identify where you have pointer-type global variables. And on the stack, you find a mixture of e.g. integers, function-call return addresses or data pointers. For both memory areas, you have to find a way to enumerate all potential pointer values.
To make things worse, a pointer can not only point to the beginning of your data structure, but also to some inside element. And this pointer also makes the whole object "live".
Regarding 2.: That's the easy part, using the algorithm you mentioned.
Regarding 3.: Now your objects live at new addresses, so your old pointer values are no longer correct (pointing to the old locations), and you have to adjust them. So once again, you have to follow all root references (like in 1.) and adjust all pointers that are affected by your moves. But as you can't tell for sure if e.g. 0x12345678 was meant as an numeric integer or as an (old-location) address, changing that to the new-location address might break some computation.
Recently, I am writing some Abstract Data Types (ADTs) for Queue in C Language.
But I found a problem for ADT in C:
How can I pass the type of data in C?
For example, in C++ I can use the template to pass type:
std::queue< struct mySt > myQ;
That template will pass "struct mySt" type to create myQ.
But how to do this in C?
All I know is to create a generic pointer pushing the data of "struct mySt" like below:
void enq(void *dataPtr);
and pop it using casting like below:
struct mySt *a = (struct mySt *) deq()
That seems work in C, but how can I perform "deep copy" action? I mean creating a new memory space for the content of the pointer dataPtr rather than just points it?
Except using Macro or Function pointer to solve this, is there other better way to solve it?
There isn't a simple way to do it in C. The C++ code relies on constructors (the copy constructor) to implement the copy, which is necessary because you can't tell a priori whether there are pointers in the class or allocated memory that need to be altered when an independent copy of the structure is made.
If you are going to copy the structures in a C ADT, then at a bare minimum you will need to specify the size of the structure to be copied as part of the interface. However, you really need a copy function that knows how to deal with the pointers in a copy of the structure.
Passing pointers around is simpler; it is clear that the object that is pointed at continues to exist unmodified by the fact that its pointer is now stored in a list.
Hello, guys!
I'm familiar with JavaScript and PHP, but new to C.
I am trying to play around with graphics in C and craete colision algorithm. Now, I need to create objects dynamically, just like in more advanced languages. For example, I need to create a polygon via my own function and make it an object that would be visible to the whole script. I assume, a struct would be needed.
As far as I know, everything declared in a function stays in a function. How can I dynamically declare global structs?
C is a fairly static language. By static I mean, you can create memory during run-time, but you will need pointers to address that memory declared at compile time. That is if you are going to need memory during run-time and do not want to declare it during compile time, you will need to use malloc and free (when you've finished with the memory).
To create a global structure whose memory you would create at run time, you would minimally need a pointer to a structure at compile time. If you need several of those structures, you could create several structures' worth of memory, but traversing the structures would be tedious without having an array of those structures. You would need that array of pointers to structures at compile time. There are some ways to make this more dynamic, but in decade or so I used C and C++, we never ran into those other ways, including in device drivers.
When you say create objects in C, you really have no objects you can create other than those created by a function call to a library or creating memory from the heap, and then interpreting that memory by overlapping structure or array pointers over it.
Functions can alter parameters if those parameters are passed in by reference (a pointer to the parameter), and functions can return nothing or return a single atom of data, a char, integer, smallint, or pointer.
a. function can return value.
b. you can use global variables.
c (and probably the most useful). dynamically allocate memory (using malloc,etc) and return pointer to it. (And remember to free it after using)
You need to have a struct or a more complex abstract data type (ADT) to hold your dynamically created variables. Once you have this, you can create the any object you want via malloc(), and store it in there.
As I mentioned earlier, it would be highly recommended to have a look at the ADTs and learn how to work with them. This will allow you to create any complex data structure like queues or linked lists in order to work a little more OOP oriented.
declare global pointers(array of pointers) of the same type as the structure. Use the functions like malloc etc. to dynamically allocate memory and assign it to the pointers.