C API String Parsing/Returning

K

k3xji

Hi all,

This might be a newbie question. I am trying to implement a simple
string decoder/encoder algorithm. Just suppose I am substrcating some
values from the string passed as a parameter to the function and I
want the function to return encoded/decoded version of the string.

Here is the call:
ss= esauth.penc('s')
st = esauth.pdec(ss)

static PyObject *
pdec(PyObject *self, PyObject *args)
{
unsigned char *s= NULL;

unsigned int v,len,i = 0;

if (!PyArg_ParseTuple(args, "s", &s))
return NULL;
if (!s)
return NULL;

len = strlen(s);

for(i=0;i<len;i++) {
if (s > 10)
s = s - 10;
}

return Py_BuildValue("s",s);
}


This is returning the original string. I mean the parameter is changed
but the Py_BuildValue is returning the original string passed in as
param.

have dealt with another nmore complex extension and because of the
same string handling problems, I just stop implementing it. Can
somebody please briefly explain the gotchas in Python's string
handling and returning values, cause I am having real trouble with
them.

Thanks,
 
K

k3xji

Sorry, Here is the correct output:µ --> how did this happen if the param and return values are same? I
cannot understand this. Something has todo with ref counts but I don't
understand the problem.


Hi all,

This might be a newbie question. I am trying to implement a simple
string decoder/encoder algorithm. Just suppose I am substrcating some
values from the string passed as a parameter to the function and I
want the function to return encoded/decoded version of the string.

Here is the call:
ss= esauth.penc('s')
st = esauth.pdec(ss)

static PyObject *
pdec(PyObject *self, PyObject *args)
{
š š š š unsigned char *s= NULL;

š š š š unsigned int v,len,i = 0;

š š š š if (!PyArg_ParseTuple(args, "s", &s))
š š š š return NULL;
š š š š if (!s)
š š š š š š š š return NULL;

š š š š len = strlen(s);

š š š š for(i=0;i<len;i++) {
š š š š š š š š if (s > 10)
š š š š š š š š š š s = s - 10;
š š š š }

š š š š return Py_BuildValue("s",s);

}

This is returning the original string. I mean the parameter is changed
but the Py_BuildValue is returning the original string passed in as
param.

šhave dealt with another nmore complex extension and because of the
same string handling problems, I just stop implementing it. Can
somebody please briefly explain the gotchas in Python's string
handling and returning values, cause I am having real trouble with
them.

Thanks,
 
G

Gerhard Häring

k3xji said:
Hi all,

This might be a newbie question. I am trying to implement a simple
string decoder/encoder algorithm. Just suppose I am substrcating some
values from the string passed as a parameter to the function and I
want the function to return encoded/decoded version of the string.

Here is the call:
ss= esauth.penc('s')
st = esauth.pdec(ss)

static PyObject *
pdec(PyObject *self, PyObject *args)
{
unsigned char *s= NULL;

unsigned int v,len,i = 0;

if (!PyArg_ParseTuple(args, "s", &s))
return NULL;
if (!s)
return NULL;

These two lines are superfluous. s now points to the contents of the
Python string (which must not contain any 0 characters, else a TypeError
is raised instead). Python strings are immutable, so you should *not
modify this C string*.
len = strlen(s);

for(i=0;i<len;i++) {
if (s > 10)
s = s - 10;
}

return Py_BuildValue("s",s);
}


This is returning the original string. I mean the parameter is changed
but the Py_BuildValue is returning the original string passed in as
param. [...]


Yes, that's because you're returning a Python string from the string
passed in ;-)

You should do something else instead:

char* buf = strdup(s);
if (!buf) {
PyErr_SetString(PyExc_MemoryError, "Out of memory: strdup failed");
return NULL;
}

/* TODO: your string manipulation */

return PyString_FromString(buf); /* return Py_BuildValue("s", buf); */

If you want to cope with Python strings that may contain 0 bytes, parse
them with "s#" instead. This should normally be better because you avoid
the strlen() this way.

HTH

-- Gerhard
 
K

k3xji

Whan I run the following function, I see a mem leak, a 20 mb of memory
is allocated and is not freed. Here is the code I run:
.... ss = esauth.penc('sumer')
........ ss = esauth.penc('sumer')
....

And here is the penc() function.


static PyObject *
penc(PyObject *self, PyObject *args)
{
unsigned char *s= NULL;
unsigned char *buf = NULL;
PyObject * result = NULL;
unsigned int v,len,i = 0;

if (!PyArg_ParseTuple(args, "s#", &s, &len))
return NULL;

buf = strdup(s);
if (!buf) {
PyErr_SetString(PyExc_MemoryError,
"Out of memory: strdup failed");
return NULL;
}


/*string manipulation*/


result = PyString_FromString(buf);
free(buf);
return result;
}


Am I doing something wrong?

Thanks,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top