2

I am importing a shared object library written in C and calling to some wrapper functions I made that work using the Python.h library.

I have a function with the following prototype:

PyObject *Cal_readFile( PyObject *self, PyObject *args );

I parse out the following tuples:

PyArg_ParseTuple(args, "sO", &filename, &result)

From python the call looks like this:

result = []
status = Cal.readFile(filename, result)
print(result)

It is called fine, and the function definitely runs. My goal is to modify that result variable within the C function that is called. And that is exactly what I do. I modify the result variable within the C function and am using result = Py_BuildValue("[lO]", (long)comp, compList); to put new data into it.

However when I then print result in Python I still have the same empty list I started with.

Is there some additional step I need to do to modify this python variable from the C function? I cannot use it in the return as you already see that I am collecting a return status from there (this return works).

Edit: Some code from readCal that may be useful:

PyObject *result = NULL;
PyArg_ParseTuple(args, "sO", &filename, &result);
//Some creating of data is done, and then I am trying to set the list to that data:

result = Py_BuildValue("[lO]", (long)comp, compList);
4
  • Do you mean you want to append these values Python list? You cannot replace a variable like that in Python, neither is it possible at all in C. Commented Mar 18, 2016 at 18:58
  • And please provide more code for the Cal_readFile Commented Mar 18, 2016 at 18:58
  • @AnttiHaapala yes, I guess appending may be the correct way then. The file is fairly big which is why I did not paste it in. I'll edit in some pieces that may be relevant. Commented Mar 18, 2016 at 19:00
  • @AnttiHaapala I added in some code that may help you. You can see that I am replacing the result value with a new list, which I guess may be the problem then as I am replacing instead of appending Commented Mar 18, 2016 at 19:02

2 Answers 2

2

You cannot replace the result altogether, but you can append values to it, or remove existing values and so forth. Something like this could do what you'd need:

if (!PyArg_ParseTuple(args, "sO", &filename, &result)) {
    return NULL;
}

PyObject *l = PyLong_FromLong((long)comp);
if (!l) {
    return NULL;
}

int success = PyList_Append(result, l);
Py_DECREF(l);
if (! success) {
    return NULL;
}

success = PyList_Append(result, complist);
if (! success) {
    return NULL;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Or perhaps use PyList_SetSlice with a tuple as now if the second append fails there will still be 1 item appended to the list
Good suggestion, but if it does fail to get the one then it is likely both have failed anyway. The first long is actually just storing the C pointer, and the 2nd part is some manipulated data from that pointer address anyway.
1

When you do:

PyArg_ParseTuple(args, "sO", &filename, &result)

you're assigning an instance reference as handled by python into the result pointer.

Then when you do:

result = Py_BuildValue("[lO]", (long)comp, compList);

you're replacing the value referenced by the result pointer by a new one. Meaning that within your python code, the result variable still points to the former instance.

If you want to modify the pointed list instance, then you shall use the List methods in C, to mutate the instance itself, instead of creating a new instance.

Basically, what you do in your C code, is the same as the following python code:

>>> def foo(result):
...    result = [4,5,6]
...
>>> result = [1,2,3]
>>> foo(result)
>>> print(result)
[1,2,3]

what you'd want is to do — in python — is:

>>> def foo(result):
...    while len(result): 
...        result.pop() # or any operation that mutates the result instance
...    result += [4,5,6]
...
>>> result = [1,2,3]
>>> foo(result)
>>> print(result)
[4,5,6]

now I leave it up to you to do it using the C API ;-)

HTH

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.