开发者

SWIG Python and C++ std::string null-termination problem [duplicate]

This question already has answers here: Closed 10 years ago.

Possible Duplicate:

How Python can get binary data(char*) from C++ by SWIG?

I have a SWIG based C++ interface that can called from Python. There is a function in it, that has one std::string argument. It looks like this:

Wrappe开发者_JAVA百科rGet(const std::string& key);

If it is called from Python with a string argument that contains NUL character (e.g. binary data), then the std::string is truncated at the NUL character, and that is my problem, because it makes impossible to handle binary data.

What makes it interesting is that other way works perfectly:

std::string WrapperResult();

The string returned here can contain binary data without truncation. Has anybody any idea what has to be done?

UPDATE: I debugged the SWIG generated code and it turned out that the error was in the wrapper code on the C++ size: it used the c_str() member function of the std::string to get the string value.

Thanks for everybody's ideas and time!


I've had to deal with this in the past, and I just grabbed the std::string conversion template from SWIG and tailored it a bit to use PyString_FromStringAndSize when creating a Python string from a std::string and the std::string constructor that accepts a size argument when going the other way.

That was with a really old version of SWIG, though - I thought the builtin conversion template in newer versions had been updated to do that automatically. Is it possible the problem is on the C++ side? (e.g. as in Mark Tolonen's examples, where the first example is truncated due to the embedded NULL in the constructor call without a size argument).


It is probably how the strings are constructed. Consider:

string blah(const string& x)
{
    string y("abc\x00def");
    return x + y;
}

string blah2(const string& x)
{
    string y("abc\x00def",7);
    return x + y;
}

Calling these from Python:

>>> import x
>>> x.blah('abc\x00def')
'abc\x00defabc'
>>> x.blah2('abc\x00def')
'abc\x00defabc\x00xyz'

The constructor for std::string(const char*) stops at the NULL, but clearly SWIG can pass in and return strings with a NULL in them.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜