Port C's fread(&struct,....) to Python - python

Hey, I'm really struggling with this one. I'am trying to port a small piece of someone else's code to Python and this is what I have:
typedef struct
{
uint8_t Y[LUMA_HEIGHT][LUMA_WIDTH];
uint8_t Cb[CHROMA_HEIGHT][CHROMA_WIDTH];
uint8_t Cr[CHROMA_HEIGHT][CHROMA_WIDTH];
} __attribute__((__packed__)) frame_t;
frame_t frame;
while (! feof(stdin))
{
fread(&frame, 1, sizeof(frame), stdin);
// DO SOME STUFF
}
Later I need to access the data like so: frame.Y[x][y]
So I made a Class 'frame' in Python and inserted the corresponding variables(frame.Y, frame.Cb, frame.Cr).
I have tried to sequentially map the data from Y[0][0] to Cr[MAX][MAX], even printed out the C struct in action but didn't manage to wrap my head around the method used to put the data in there. I've been struggling overnight with this and have to get back to the army tonight, so any immediate help is very welcome and appreciated.
Thanks

You have to use struct python standard module.
From its documentation (emphasys added):
This module performs conversions
between Python values and C structs
represented as Python strings. It uses
format strings (explained below) as
compact descriptions of the lay-out of
the C structs and the intended
conversion to/from Python values. This
can be used in handling binary data
stored in files or from network
connections, among other sources.
Note: as the data you are reading in the end is of a uniform format, you could also use the array module and then "restructure" the data in Python, but I think the best way to go is by using struct.

Related

Create a python like list in c++

I have a python script that I have to translate in c++, and 80 % of my python script is based on lists.
I have a file that I read, and put the data of that file in a list :
//Code to translate in c++
bloc = [line]
for b in range(11):
bloc.append(lines[i + 1])
i += 1
I make my stuff with that data and then, I do it again until I read the whole file.
And finally I want to be able to get data of this list doing something like :
#Python script
var = bloc[0, 1, 2, 3 ...]
I'll respond to any questions you need more infos
The C++ container closest to a python List is a std::vector. However contrary to python a std::vector contains only one type of element. You have to declare what the vector will hold.
In your case it would be std::string (reading from a file).
So:
std::vector<std::string> cpp_list; // container for lines (stored as string )from the file
is equivalent to python python_list = []
should get you started.
With a std::vector you do not strictly need to allocated storage upfront but for performance reason it is better to do is if you know the required size in advance.
if you use cpp_list.reserve(something) or do not do any memory allocation, you must push in the vector using cpp_list.push_back(...) which is similar to pyhton_list.append(...)
If you allocate memory upfront eg: std::vector<std::string> cpp_list(nb_lines)
You must use indexing as in python eg cpp_list[3] = something

Workflow: C pointer to Python array?

I am writing some code in C, which reads data in and stores it in a pointer of type;
uint8_t
This data I now want to make accessible in Python3.
For now I have figured out how to make my C code callable with the help of ctypes and I know it works since I am able to print my data out in the Python terminal, but not able to store it in a variable.
My problem lies in that I do not know how to transform this pointer into an array which can be stored and manipulated in Python, so therefore I ask, if someone has a simple example where they move for an example a 3 by 1 array from C into Python, and then are able to work with it there, it would benefit me a lot.
Okay, so I managed to figure it out, maybe not the smartest way, but atleast it works now. Since I return a pointer of the type, ``` u_int8 * ```` in C, I amble then in Python to use something like this:
g = (ctypes.c_float*5271).from_address(a)
And then g[0], g[:], etc. to get the data etc.

C++ Pointer to Numpy Array

Briefly:
Is there an efficient way to make a numpy array given a pointer in memory to the array, it's type, and the number of elements?
More detail:
I am working with a python framework which has an object.GetData() command that is supposed to return a pointer to the data (an array of 35,000 int8) of this object.
I'm supposed to be able efficiently load these integers to a numpy array through
arr = numpy.frombuffer(object.GetData(),count=35000,dtype="int8")
but this doesn't seem to work. I get an error message ValueError: buffer is smaller than requested size. Changing the length, I can get it to output an array, but typically less than 20 integers in length (usually 0 or 1 integers).
I believe I can access the pointer to the start of the array, in hex form, through
hex(id(object.GetData()))
which looks like it gives addresses (e.g. 0x10fd8c670) but I don't know if this is the actual address.
I'm more comfortable in python than c++, but there could be a bug in the c++ code. The c++ code for GetData is:
const _Tp* GetData() const
{
// Return a const pointer to the internal data
return (fData.size() > 0 ) ? &(fData)[0] : NULL;
}
where fdata is initialized as a VecType through:
VecType fData;
Right now I can access each element of the object's data through an object.At(i) command where i is the index of the data array of object, but it is very slow to load each element into a numpy array this way, and I'm dealing with a lot of data. For reference, the At command in the c++ code does this:
_Tp At(size_t i) const
{
return fData.at(i);
}
Any help would be appreciated. I don't have a ton of experience with pointers, and even less with pointers in python, but I would like to figure this out in python rather than re-write all my code in c++. Thanks!

Parse C Array Size with Python & LibClang

I am currently using Python to parse a C file using LibClang. I've encountered a problem while reading a C-array which size is defined by a define-directive-variable.
With node.get_children i can perfectly read the following array:
int myarray[20][30][10];
As soon as the array size is replaced with a variable, the array won't be read correctly. The following array code can't be read.
#define MAX 60;
int myarray[MAX][30][10];
Actually the parser stops at MAX and in the dump there is the error: invalid sloc.
How can I solve this?
Thanks
Run the code through a C preprocessor before trying to parse it. That will cause all preprocessor-symbols to be replaced by their values, i.e. your [MAX] will become [60].
Note that C code can also do this:
const int three[] = { 1, 2, 3 };
i.e. let the compiler deduce the length of the array from the number of initializer values given.
Or, from C99, even this:
const int hundred[] = { [99] = 4711 };
So a naive approach might still break, but I don't know anything about the capabilities of the parser you're using, of course.
Semicolon ; in the define directive way causing the error.

Python regex to extract data from C header file

I have a C header file with a lot of enums, typedefs and function prototypes. I want to extract this data using Python regex (re). I really need help with the syntax, because I constantly seem to forget it every time I learn.
ENUMS
-----
enum
{
(tab character)(stuff to be extracted - multiple lines)
};
TYPES
-----
typedef struct (extract1) (extract2)
FUNCTIONS
---------
(return type)
(name)
(
(tab character)(arguments - multiple lines)
);
If anyone could point me in the right direction, I would be grateful.
I imagine something like this is what you're after?
>>> re.findall('enum\s*{\s*([^}]*)};', 'enum {A,B,C};')
['A,B,C']
>>> re.findall("typedef\s+struct\s+(\w+)\s+(\w+);", "typedef struct blah blah;")
[('blah', 'blah')]
There are of course numerous variations on the syntax, and functions are much more complicated, so I'll leave those for you, as frankly these regexps are already fragile and inelegant enough. I would urge you to use an actual parser unless this is just a one-off project where robustness is totally unimportant and you can be sure of the format of your inputs.

Categories

Resources