Python Forum
Python C API - Issue with string as arugments - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Python C API - Issue with string as arugments (/thread-22808.html)



Python C API - Issue with string as arugments - JRHeisey - Nov-27-2019

Greetings,

Using Python 3.4.3
  • I am creating a PyUnicode string from a C string.
  • I am passing this string as a argument to a Python function from C.
  • In the setter function I can print out parameter.
  • When I assign the parameter to an array then print out the array the string value is corrupted.
  • I've been referencing PEP 393
  • Performing the same activity in purely Python prints out the string argument and array fine.

I have tried using these C functions to create the PyUnicode string and they all behave the same way.
Output:
// C code to create a PyUnicode string and set it into a tuple void SetParameter(PyObject * pTuple, const char * psValue, unsigned int uPosition) { // PyObject * obj = PyUnicode_FromStringAndSize(psValue, strlen(psValue)); // PyObject * obj = _PyUnicode_FromASCII(psValue, strlen(psValue)); // PyObject * obj = PyUnicode_FromFormat("%s", psValue); PyObject * obj = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, psValue, strlen(psValue)); PyTuple_SetItem(pTuple, uPosition, obj); }
# Python 3 function receiving the tuple with a strings
def configure(self, ip1, ip2, ip3):
    print ("configure[ip list]", ip1, ip2, ip3)
    self.string_args.append('--ip')
    self.string_args.append(ip1)
    self.string_args.append('--ip')
    self.string_args.append(ip2)
    self.string_args.append('--ip')
    self.string_args.append(ip3)
    print ("configure[self.string_args]", self.string_args)
Output:
# Printed output when configure() is executed from C configure[ip list] 127.0.0.1 127.0.0.1 127.0.0.1 configure [self.string_args] ['--ip', ''27.0.0.1', '--ip', "\"\\\"\\\\\\, '--ip', '"\\"\\\\\\"\\\\\\\\\\\\', '--ip', '"\\"\\\\\\"\\\\\\\\\\\\']
Output:
# Printed output when configure() is executed from Python $ ./Test.py configure [ip list] 127.0.0.1 127.0.0.2 127.0.0.3 configure [self.string_args] ['--ip', '127.0.0.1', '--ip', '127.0.0.2', '--ip', '127.0.0.3']
Due to the difference in behavior I conclude that it is something about the way the C code creates the PyUnicode objects. Perhaps I need to create some other object type?

I have the source for the C Python engine but I haven't figure it out yet.


RE: Python C API - Issue with string as arugments - JRHeisey - Nov-27-2019

I have discovered a less efficient workaround.
Output:
I replaced the three calls to SetParameter() with this PyObject * arguments = Py_BuildValue("(sssi)", ipAddress1, ipAddress2, ipAddress3, timeout); PyObject * result = PyObject_CallObject(pyfunction, arguments); // Assuming that pyfunction is already created. // And 'arguments' and 'result' are properly decremented there reference counts.
I would prefer to not deallocate the tuple each time.


RE: Python C API - Issue with string as arugments - casevh - Nov-30-2019

Since you haven't provided enough source code, I can only make some general comments.

How do you create pTuple?

You aren't checking the return value of of PyTuple_SetItem() or Py_BuildValue() or any of the PUnicode_() functions. You really should get in the habit of checking the return value.

I don't understand why you don't like the Py_BuildValue() option. It is simpler code. And you should be deleting pTuple after your call back to Python. If you don't delete the tuple (either pTuple or arguments), how are you decrementing the reference counts for objects contained in the tuple?

casevh