I have a task to analyze declaration of functions in c in python.
My regex finds all functions but it finds also declarations that are commented which is wrong like example:
unsigned int *hashfn(const char *str, ...);
//unsigned int *hash_function(const char *str, unsigned int htab_size);
I need to ignore second function.
Any ideas?
I have a C++ class method like this:
class BinaryData
{
public:
...
void serialize(unsigned char* buf) const;
};
serialize function just get binary data as unsigned char*.
I use SWIG to wrap this class.
I want to read binary data as byte array or int array in python.
Python Code:
buf = [1] * 1000;
binData.serialize(buf);
But it occurs exception that can't convert to unsigned char*.
How can I call this function in python?
Simplest thing to do is to convert it inside Python:
buf = [1] * 1000;
binData.serialize(''.join(buf));
Will work out of the box, but is potentially inelegant depending on what Python users are expecting. You can workaround that using SWIG either inside Python code, e.g. with:
%feature("shadow") BinaryData::serialize(unsigned char *) %{
def serialize(*args):
#do something before
args = (args[0], ''.join(args[1]))
$action
#do something after
%}
Or inside the generated interface code, e.g. using buffers protocol:
%typemap(in) unsigned char *buf %{
// use PyObject_CheckBuffer and
// PyObject_GetBuffer to work with the underlying buffer
// AND/OR
// use PyIter_Check and
// PyObject_GetIter
%}
Where you prefer to do this is a personal choice based on your preferred programming language and other situation specific constraints.
I am using swig, which is wrapping one of my C++ function:
get(unsigned int a, unsigned int &b);
but i am failing to call this function from python, the error i get is TypeError that it should be unsigned int&
how call to this function from python ? should i add something special to the .i file ?
Yes,you should add typemaps.
example:
export.i:
%module my_mod
%include "typemaps.i"
%apply unsigned int &OUTPUT {unsigned int&}; //this map you output
%include "export.h"
export.h
void get(unsigned int a, unsigned int& b);
test
print(my_mod.get(10))
How can I get a char* from a PyObject which points to a string. For example, this is the python script,
Test.Connect("272.22.20.65", 1234)
and this is the C++ code,
static PyObject* Connect(PyObject *self, PyObject *args)
{
PyObject* pIP;
PyObject* pPort;
if (!PyArg_UnpackTuple(args, "Connect", 2, 2, &pIP, &pPort))
{
return NULL;
}
const char* zIP = GetAsString(pIP);
long iPort = PyLong_AsLong(pPort);
I want to get that IP address as a char* (GetAsString is a dummy function :D ). Please note that I'm using Python 3.1.
P.S.
I don't think this question got the correct answer ,
since there is no PyStringObject or PyString_AsString in Python 3. Isn't it ?
First you encode it, then you retrieve it. Don't forget to decref the temporary.
Here is my portable recipe for it, which makes use the default encoding, where that is applicable. It assumes you start with a PyObject*, named o. If you still have your input tuple from the function call, you can skip the first 2 lines.
PyObject* args = Py_BuildValue("(O)", o);
/* Py_DECREF(o); if o is not borrowed */
if (!args) return 0;
const char* s = 0;
if (!PyArg_ParseTuple(args, "s", &s)) {
Py_DECREF(args);
return 0;
}
/* s now points to a const char* - use it, delete args when done */
Py_DECREF(args);
PS: I have not tested it, but it should work with older versions of Python as well. There is nothing on it which is version specific.
I've got a C python extension, and I would like to print out some diagnostics.
I'm receiving a string as a PyObject*.
What's the canonical way to obtain a string representation of this object, such that it usable as a const char *?
Use PyObject_Repr (to mimic Python's repr function) or PyObject_Str (to mimic str), and then call PyString_AsString to get char * (you can, and usually should, use it as const char*, for example:
PyObject* objectsRepresentation = PyObject_Repr(yourObject);
const char* s = PyString_AsString(objectsRepresentation);
This method is OK for any PyObject. If you are absolutely sure yourObject is a Python string and not something else, like for instance a number, you can skip the first line and just do:
const char* s = PyString_AsString(yourObject);
Here is the correct answer if you are using Python 3:
static void reprint(PyObject *obj) {
PyObject* repr = PyObject_Repr(obj);
PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "~E~");
const char *bytes = PyBytes_AS_STRING(str);
printf("REPR: %s\n", bytes);
Py_XDECREF(repr);
Py_XDECREF(str);
}
If you need just print the object in Python 3 you can use one of these functions:
static void print_str(PyObject *o)
{
PyObject_Print(o, stdout, Py_PRINT_RAW);
}
static void print_repr(PyObject *o)
{
PyObject_Print(o, stdout, 0);
}
Try PyObject_Repr (to mimic Python's repr) or PyObject_Str (to mimic Python's str).
Docs:
Compute a string representation of
object o. Returns the string
representation on success, NULL on
failure. This is the equivalent of the
Python expression repr(o). Called by
the repr() built-in function.
For python >=3.3:
char* str = PyUnicode_1BYTE_DATA(py_object);
Yes, this is a non-const pointer, you can potentially modify the (immutable) string via it.
PyObject *module_name;
PyUnicode_AsUTF8(module_name)
For an arbitrary PyObject*, first call
PyObject_Repr() or PyObject_Str() to get a PyUnicode* object.
In Python 3.3 and up, call PyUnicode_AsUTF8AndSize. In addition to the Python string you want a const char * for, this function takes an optional address to store the length in.
Python strings are objects with explicit length fields that may contain null bytes, while a const char* by itself is typically a pointer to a null-terminated C string. Converting a Python string to a C string is a potentially lossy operation. For that reason, all the other Python C-API functions that could return a const char* from a string are deprecated.
If you do not care about losing a bunch of the string if it happens to contain an embedded null byte, you can pass NULL for the size argument. For example,
PyObject* foo = PyUnicode_FromStringAndSize("foo\0bar", 7);
printf("As const char*, ignoring length: %s\n",
PyUnicode_AsUTF8AndSize(foo, NULL));
prints
As const char*, ignoring length: foo
But you can also pass in the address of a size variable, to use with the const char*, to make sure that you’re getting the entire string.
PyObject* foo = PyUnicode_FromStringAndSize("foo\0bar", 7);
printf("Including size: ");
size_t size;
const char* data = PyUnicode_AsUTF8AndSize(foo, &size);
fwrite(data, sizeof(data[0]), size, stdout);
putchar('\n');
On my terminal, that outputs
$ ./main | cat -v
Including size: foo^#bar