Почему бы просто не вызвать PyArg_ParseTuple со строкой, которую вы получаете при вызове StringIO.getvalue()
?
С чем-то вроде этого?
const char* cstring;
if (!PyArg_ParseTuple(args,"s", &cstring)) //Note the &
return NULL;
std::string stdstring = cstring;
std::stringstream buffer(stdstring);
Также см. C API для cStringIO here .
После дополнительных требований я попытался найти решение с использованием SWIG в рамках фиксированных ограничений.
Первым возможным решением было встроенное или расширяемое решение (расширить StTest довозьмите строку и затем сделайте расширение, сделайте stringstream и вызовите StTest), но, поскольку в приведенном примере есть только один метод и нет классов, это не соответствует ограничениям.
Возможный интерфейсный файл выглядел следующим образом.
/* test.i */
%module test
%{
#include "test.h"
#include <sstream>
#include <iostream>
%}
using namespace std;
%include "std_sstream.i"
%include "test.h"
%include <typemaps.i>
%typemap(in) std::stringstream & (char *buf = 0, size_t size = 0, int alloc = 0, std::stringstream stream)
{
if (SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc) != SWIG_OK)
{
%argument_fail(SWIG_TypeError, "(TYPEMAP, SIZE)", $symname, $argnum);
}
stream.write(buf, size - 1);
$1 = &stream;
}
Обратите внимание, что SWIG проигнорировал карту типов в приведенном выше файле интерфейса, но не уверен, почему.Ему удалось создать объекты потока строк в Python, но они не были бы переданы вашему StTest, что приводило к той же ошибке типа, потому что тип объектов не был типом потока строк & (также сопоставленный тип swig несоответствовать типам, сгенерированным std_sstream.i, возможно потому, что он не содержит сопоставления типов).
Далее была реализация подхода, предложенного мной для переопределения оболочки SWIG, получившаяся в результате функция-обертка выглядела следующим образом.(Не будет включать весь файл-обертку, так как он имеет длину более 18000 строк)
SWIGINTERN PyObject *_wrap_StTest(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
int argc;
PyObject *argv[3];
int ii;
char *cstring;
std::stringstream testbuffer;
if (!PyTuple_Check(args)) SWIG_fail;
argc = args ? (int)PyObject_Length(args) : 0;
for (ii = 0; (ii < 2) && (ii < argc); ii++) {
argv[ii] = PyTuple_GET_ITEM(args,ii);
}
if (argc == 1) {
if (!PyArg_ParseTuple(args,"s",&cstring))
SWIG_fail;
std::string teststring = cstring;
testbuffer.str(cstring);
std::cout << "the string in the stream: " << testbuffer.str() << std::endl;
}
StTest(testbuffer);
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
Строка в строке потока печатается правильно, однако передача строкового потока в функцию StTest печатает местоположение в памяти потока строки,Это ожидается, потому что поток строк не связан, как в принятом ответе следующего вопроса переполнения стека .
Я предполагаю, что StTest(testbuffer);
можно заменить версией, использующей привязку boost, и она будет работать по мере необходимости, но была в состоянии проверить.
Ссылки, которые были полезны, включали