Hi,
I posted a question over at stack overflow but figured I should ask it here as well. It feel like a somewhat basic question but I’m getting stuck so need some ideas for what to test.
You can see the answer at: http://stackoverflow.com/q/24518246/3757019
I’m posting the same info here:
I’m working on wrapping my first few C++ classes in Cython and was lucky to get through the first few simple ones. Now I’m getting a bad_ptr
error in the constructor for a C++ class that takes in a std::string name
argument. I have not been able to correctly figure out how to convert a Python string
to a C++ std::string
. Below is what I’m currently doing. What do I need to change?
For information I use latest cython 0.20.2
, python 3.4 (32bit)
on a Windows 7
machine and I use Visual Studio 2010
for compilation. I suspect the python 3.x
could play into it since they have mucked with string definitions but I’m not sure how.
Here is the CPP Class definition I have:
class HDMISOURCE_API Source: public TipInterface
{
public:
Source(std::string name, Interface* env);
...
I want to expose this class to python through a cython class that simply takes in a name argument (and keeps the pointer internally).
Here is the relevant cython code I have:
from libcpp.string cimport string
cdef extern from "EnvironmentSelect.h":
_TipUserEnvironmentInterface* _GetEnvironment "GetEnvironment" ()
cdef extern from "HDMISource.h":
cdef cppclass _HDMISource "HDMISource":
_HDMISource(string, _TipUserEnvironmentInterface*) except +
cdef class HDMISource:
cdef _HDMISource* thisptr
def __cinit__(self, string pin_map):
env = _GetEnvironment()
self.thisptr = new _HDMISource(pin_map, env)
def __dealloc__(self):
del self.thisptr
def hello(self):
print('HDMISource still says hello!')
To debug this I compile using Visual Studio 2010 and with debug flags. I then start python and from visual studio do attach to process
. Then from the python prompt
I do this:
c:\Projects\psvm\python\tip>python
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import tip
>>> name = 'MyHDMITxPins'.encode('UTF-8')
>>> type(name)
<class 'bytes'>
>>> hdmi = tip.HDMISource(name)
At this point I get a break point in the generated code (tip.cpp) and at that level the name is a std::basic_str
with the correct value. I wonder if std::basic_str is what I want it to be though…
If I step through some of the code I arrive at the class I expect:
HDMISource::HDMISource(std::string pinMap, TipUserEnvironmentInterface* env): TipInterface(pinMap, dynamic_cast<TipEnvironmentInterface*>(env)), m_videoFrameNum(0)
{
...
}
But at this point the std::string PinMap
reports as bad_ptr
so somehow I’ve lost the string on my way down the hierarchy… (And I was so convinced it would be the other class pointer that would be the issue and it seem fine!).
If I let it run I get this in the python window:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "tip.pyx", line 60, in tip.HDMISource.__cinit__ (tip.cpp:1201)
self.thisptr = new _HDMISource(pin_map, env)
RuntimeError: Unknown exception
>>>
It feels like I need to do something more in the cython
code to convert to/from python string
and std::str
but I can’t figure out what. Please help! I will be forever grateful!