0

I was wondering if I could get some help. Say I've got the following function to serialize an object:

PyObject * CKKSwrapper::SerializeContext() {
    std::string s;
    std::ostringstream os(s);
    Serial::Serialize(m_cc, os, SerType::BINARY);

    const std::string tmp = os.str();
    const char *msg = tmp.c_str();
    std::cout << "Length of context: " << tmp.length() << "\n";
    return PyBytes_FromString(msg);
}

The Boost module file has

BOOST_PYTHON_MODULE (pycrypto) {
    class_<pycrypto::CKKSwrapper>("CKKSwrapper")
        .def("SerializeContext", &pycrypto::CKKSwrapper::SerializeContext,
             return_value_policy<manage_new_object>());

where I am managing the object.

However, when I call the method in Python, I get a None object, and the output is

import pycrypto
a = pycrypto.SerializeContext()

a is None and I get Length of context: X to my console

IanQ
  • 1,831
  • 5
  • 20
  • 29
  • 1
    Can you try and swap `"\n"` with `std::endl`? Reason is that `std::endl` flushes the buffer so it ensures you don't get partial output. – unddoch Mar 30 '21 at 23:17
  • 1
    Also - note that using `PyBytes_FromString` is a very bad idea if your serialization data can contain null bytes. – unddoch Mar 30 '21 at 23:19
  • gotcha! Thanks! `std::endl` so, it's actually outputting the value just fine. In lieu of `PyBytes_FromString` what would you suggest? I've been looking around for memoryview resources but most of them are rather surface level in that they don't really discuss how to create it in C++ then pass it off to Python – IanQ Mar 30 '21 at 23:22
  • 1
    To clarify - do you mean by "Length of context: X" some random number or the letter "X" literally? I would try to just return the `std::string` object and let boost handle the conversion, I think it's supported. If not, maybe `PyBytes_FromStringAndSize` is a better fit? – unddoch Mar 30 '21 at 23:28
  • Ahh, X a random number. The issue is that I'm trying to move away from strings (the current implementation) and move towards something native to Python for speed purposes – IanQ Mar 30 '21 at 23:32
  • 1
    If your issue is speed, did you profile to see that's it's really the std::string things that take time? Maybe you can skip conversion to python types altogether and work with wrapped c++ types. Depends on how you're using the serialized data afterwards, of course. – unddoch Mar 31 '21 at 10:13
  • Actually, the issue isn't `std::string` itself. The issue is that on the Python end I need to convert it to bytes to be sent via sockets. The bytes function takes a long time so I figured that if I could get it into byte form on the C++ end, I could avoid needing to call python's `bytes` function – IanQ Mar 31 '21 at 15:20
  • If you're on Linux, you can pass the socket's fd to a c++ only function that does serialization+sending without crossing language barriers. (There's probably a way to do this on Windows, but I'm not familiar with writing Windows networking code) – unddoch Mar 31 '21 at 15:54

0 Answers0