2016-11-14 3 views
2

Ich möchte eine C++ - Zeichenfolge in einer Nogil-Funktion in einer Datei erstellen, die über pxd cimportiert werden würde. Wenn ich string output = "" oder string output = string ("blah") definiere, benutzt dies den Python-Interpreter. Gibt es eine Möglichkeit, die einen String zu definieren, so dass der Compiler in der cython CPP-Datei schreibt:cython create string mit nogil

std::string val = "blah"; 

Im Grunde ist dies haben:

from libcpp.string cimport string 
cdef string my_func() nogil: 
    cdef: 
     string output = "blah" 
    .... 
    return output 

Antwort

2
%%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() 

Dann py_call() Aufruf gibt b'blah', dh ein Byte Objekt.

EDIT: Hier ist der generierten 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 buchstäblich wirft char*-std::string.

Eine Alternative ist dann der Konstruktor von char* aufzurufen:

cdef: 
    char* c_str = 'blah' 
    string output = string(c_str) 

die erzeugt

+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; 

die besser aussieht.