Reputation: 2617
I would like to create a c++ string in a nogil function in a file that would be cimported via pxd. If I define, string output = "" or string output = string("blah"), this uses the python interpreter. Is there a way to define the a string so that the compiler writes in the cython cpp file:
std::string val = "blah";
Basically have this:
from libcpp.string cimport string
cdef string my_func() nogil:
cdef:
string output = "blah"
....
return output
Upvotes: 3
Views: 781
Reputation: 26040
%%cython -a
#distutils: language = c++
from libcpp.string cimport string
cdef string my_func() nogil:
cdef:
char* c_str = 'blah'
string output = <string>(c_str)
return output
def py_call():
return my_func()
Then calling py_call()
gives b'blah'
, i.e. a bytes object.
EDIT: Here's the generated C++ code:
+08: char* c_str = 'blah'
__pyx_v_c_str = ((char *)"blah");
+09: string output = <string>(c_str)
__pyx_v_output = ((std::string)__pyx_v_c_str);
So it literally casts char*
to std::string
.
An alternative is then to invoke the constructor from char*
:
cdef:
char* c_str = 'blah'
string output = string(c_str)
which generates
+08: char* c_str = 'blah'
__pyx_v_c_str = ((char *)"blah");
+09: string output = string(c_str, 4)
try {
__pyx_t_1 = std::string(__pyx_v_c_str, 4);
} catch(...) {
#ifdef WITH_THREAD
PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
#endif
__Pyx_CppExn2PyErr();
#ifdef WITH_THREAD
PyGILState_Release(__pyx_gilstate_save);
#endif
__PYX_ERR(0, 9, __pyx_L1_error)
}
__pyx_v_output = __pyx_t_1;
which looks better.
Upvotes: 3