memory handling in C extension

Brad Hards bhards at bigpond.net.au
Tue Dec 24 21:18:18 EST 2002


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

G'day and season's greetings,

I am working on an wrapper for Service Location Protocol
(RFC2608 and others), and am not certain I am handling
memory correctly.

Here is some example code:
<example>
#include <Python.h>
#include <slp.h>

static PyObject *
slp_getproperty(self, args)
    PyObject *self;
    PyObject *args;
{
    char *property;
    const char *propvalue;

    if (!PyArg_ParseTuple(args, "s", &property))
        return NULL;
    propvalue = SLPGetProperty(property);
    if (NULL == propvalue) {
	PyErr_Format(PyExc_NameError,
		     "Can't get value for property %s",
		     property);
	return 0;
    }
    return Py_BuildValue("s", propvalue);
}

static PyObject *
slp_findscopes(self, args)
    PyObject *self;
    PyObject *args;
{
    SLPError    result;
    SLPHandle   hslp;
    char*       scopes;

    /*FIXME - need to handle language in a better way */
    if(SLPOpen("en",SLP_FALSE,&hslp) == SLP_OK)
    {
        result = SLPFindScopes(hslp,&scopes);
        if(result == SLP_OK)
        {
           printf("%s\n",scopes);
	   //           SLPFree(scopes);
        }

        SLPClose(hslp);
    }
    return Py_BuildValue("(s)", scopes);
}

static PyMethodDef SLPMethods[] = {
    {"getproperty",  slp_getproperty, METH_VARARGS, "Read properties from SLP daemon"},
    {"findscopes",  slp_findscopes, METH_VARARGS, "Get tuple of all available scopes"},
    {NULL, NULL, 0, NULL}        /* Sentinel */
};

void
initslp(void)
{
    (void) Py_InitModule("slp", SLPMethods);
}
</example>

Question 1. I assume that I am borrowing a reference to the arguments,
if any, and that because the function call is synchronous, I am
protected. True?

Question 2. slp_getproperty() returns a string pointer, which will be free()'d
by the python interpreter when no longer referenced. If I do
something like:
<sample>
bradh at squirt python $ python
Python 2.2.1 (#1, Oct  4 2002, 09:50:49)
[GCC 2.95.3 20010315 (release)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import slp
>>> slp.getproperty("net.slp.securityEnabled")
'true'
</sample>
then the string will be free()'d by the time I get the next prompt.
That is bad, because the API says "do not free()". So I need to
duplicate the string, and return the duplicate, which can be
free()'d by the interpreter without violating the API. Is this true?
Is there a better way?

Question 3. slp_findscopes() would normally use SLPFree() on
the return string. This is not equivalent to free() in the library I am
using (it is a wrapper, but it also tracks memory usage). Is there
any way to get python to use an alternative call to free memory
(ie get SLPFree() rather than free())? Or am I going to have to
malloc() myself a new string, duplicate the old string, and then
SLPFree() the old string?

Question 4. The current slp_findscopes() returns a tuple consisting
of a single string. That is OK for now, but I'd really like to split the
string (it is a comma delimited set of scope names) into a tuple
consisting of a variable number of strings - one per scope. I can't
see how to do this with PyBuildValue().
http://www.python.org/doc/current/ext/buildValue.html seems to
imply I need to know how many elements are to be included. Any
tips? Another Build function?

Brad

- -- 
http://linux.conf.au. 22-25Jan2003. Perth, Aust. I'm registered. Are you?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE+CRVqW6pHgIdAuOMRAl7TAKCUomkG9xhJW7e0dpvCxND2aeZFtQCeMTs0
zYM8aChSd+7+gqEsSoAiW4s=
=pKQZ
-----END PGP SIGNATURE-----





More information about the Python-list mailing list