Python API 'char *&' string pointer - MStreamUtils.readCharBuffer() TypeError

Python API 'char *&' string pointer - MStreamUtils.readCharBuffer() TypeError

Anonymous
Not applicable
1,302 Views
3 Replies
Message 1 of 4

Python API 'char *&' string pointer - MStreamUtils.readCharBuffer() TypeError

Anonymous
Not applicable

I'm looking for a little insight into how to properly use the MStreamUtils.readCharBuffer() function from Maya Python API 1.0.  I'm using it to read binary data in a custom MPxData class, following the example from blindDoubleDataCmd.py and adapting the code to store/retrieve string data instead of double data.

According to the C++ documentation for the function, the arguments should be as follows:

MStatus readCharBuffer(std::istream & in,
  char *& value,
  unsigned int length,
  bool binary = false 
 )

 

This mirrors the arguments for MStreamUtils.writeCharBuffer(), with the exception of the value parameter, which here should be a variable into which the read data will be stored.  There are examples of this throughout the 1.0 Python API that work fine.  Normally you just instantiate a variable of the relevant type and pass that variable (or a pointer for immutable types) to the function, then after the function runs that variable gets updated with the data desired from the function.  Sometimes it's a little more complicated because of how Python treats some basic data types without using pointers, and you use the MScriptUtil module to make it work.  With the readCharBuffer() function I have tried all sorts of different approaches, but I can't seem to find one that allows the function to run without throwing an error.

The basic approach of passing a string variable as the value argument results in a TypeError exception complaining about the data type:

// Error: line 0: TypeError: (...): in method 'MStreamUtils_readCharBuffer', argument 2 of type 'char *&' // 

 

Now, there is no data type in Python directly equivalent to 'char *&', but elsewhere in the API documentation it implies that 'char *' and the Python str() types should be interchangeable.  In fact, writeCharBuffer() expects 'char *' for its second argument, and passing it a python string works just fine.

 

It does make sense that passing a string here doesn't work as expected, because strings are immutable in python and therefore a string variable wouldn't be able to be updated by the readCharBuffer() function outside of its local scope.  What I can't figure out, however, is what can be done to pass an appropriate pointer in its place.  I have tried to look into MScriptUtil, but it doesn't seem to have any methods related to working with strings.  There are some functions for working with char data, but I can't figure out how to make it work.  I have tried initializing an MScriptUtil instance as an int array with the expected length to be read, and creating a pointer with MScriptUtil.asCharPtr(), but that simply returns a python string.  I tried MScriptUtil.asUcharPtr(), which does give a SWIG object reference, but the readCharBuffer() function still throws the same type error.  Does anyone have a hint on how to proceed?  I'm limited to using the Python API 1.0 because the Python API 2.0 has a bug where MPxNode.writeBinary() is not passed any arguments, when it should be passed the output stream object to write to.

0 Likes
Accepted solutions (1)
1,303 Views
3 Replies
Replies (3)
Message 2 of 4

Anonymous
Not applicable

A little further investigation has led me to believe that the MScriptUtil.asCharPtr() method should be correct.  The fact that MScriptUtil.asCharPtr() returns a string, instead of a Swig Object, must be a bug with the python api.  If I am correct, that leaves us with no way to use the MStreamUtils.readCharBuffer() function with this api version unless the bug is fixed.

0 Likes
Message 3 of 4

cheng_xi_li
Autodesk Support
Autodesk Support
Accepted solution

Hi,

 

Are you refering to MPxData.writeBinary instead of MPxNode.writeBinary? It should be working. The sample(pyBlindDoubleDataCmd.py) in the devkit is incorrect. Python API 2.0 writing functions return string for ASCII and byteArray for binary. Conversion between iostream and bytearray is handled by the wrapper.

 

My modified version is here. I tested it with Maya 2018 Update 4 and it works fine.

 

For Python API 1.0, MScriptUtil.asCharPtr is a known issue. Maya is moving to Python API 2.0, if Python API 2.0 could work for you, it'd be better to use it.

 

Yours,

Li

0 Likes
Message 4 of 4

Anonymous
Not applicable

You are correct.  I did mean MPxData.  I've been staring at code and docs for so long banging my head at this problem that I haven't been able to form clear thoughts.  So the example code for the 2.0 API is incorrect?  The functions should be returning the output instead of writing it to a stream?  That makes a lot more sense then what they showed in the code since it is much more pythonic.  I can see now how the 2.0 documentation for MPxData illustrates that the functions need to return data of certain types.  I hope they get the examples updated to reflect the correct usage to avoid anymore confusion.

0 Likes