I am trying to expose a C++ library to python using boost-python. The library actually wraps an underlying C api, so uses raw pointers a lot.
// implementation of function that creates a Request object
inline Request Service::createRequest(const char* operation) const
{
blpapi_Request_t *request;
ExceptionUtil::throwOnError(
blpapi_Service_createRequest(d_handle, &request, operation)
);
return Request(request);
}
// request.h
class Request {
blpapi_Request_t *d_handle;
Element d_elements;
Request& operator=(const Request& rhs); // not implemented
public:
explicit Request(blpapi_Request_t *handle);
Request(RequestRef ref);
Request(Request &src);
};
// request.cpp
BOOST_PYTHON_MODULE(request)
{
class_<blpapi_Request_t>;
class_<Request, boost::noncopyable>("Request", init<blpapi_Request_t *>())
.def(init<Request&>())
;
}
Although request.cpp compiles successfully, when I try and use the object I get the following error:
// error output
TypeError: No to_python (by-value) converter found for C++ type: class Request
In-order to call this the python code looks like:
from session import *
from service import *
from request import *
so = SessionOptions()
so.setServerHost('localhost')
so.setServerPort(8194)
session = Session(so)
# start sesssion
if not session.start():
print 'Failed to start session'
raise Exception
if not session.openService('//blp/refdata'):
开发者_如何学运维 print 'Failed to open service //blp/refdata'
raise Exception
service = session.getService('//blp/refdata')
request = service.createRequest('ReferenceDataRequest')
The other objects (SessionOptions, Session, Service) etc are also c++ objects that I have successfully created boost-python wrappers for.
As I understand from the boost-python docs this has something to do with passing a raw pointer around, but I don't really understand what else I should do ...
Your class_<blpapi_Request_t>;
does not declare anything; is that code the correct version?
If so, then update it:
class_<blpapi_Request_t>("blpapi_Request_t");
That said, what that error indicates is that you are trying to use the Request object with an automatic conversion to a python object which has not been defined.
The reason you get this error is because you have wrapped Request as boost::noncopyable, then provided a factory method which returns a Request object by value; the boost::noncopyable means no copy constructors are generated and therefore there's no automatic to-python converter.
Two ways out of this: one is to remove the noncopyable hint; the other would be to register a converter which takes a C++ Request and returns a Python Request object. Do you really need the noncopyable semantics for Request?
精彩评论