kosta5
kosta5

Reputation: 1138

ctypes python std::string

I am working with ctypes using C++ as the backend. Now there is a function like this in C++:

void HandleString(std::string something){

   ...
}

I am wondering how to call this function from python - there is no ctype (c_char_p wont work obviously) to send a string parameter to this function...

How can I fix this and pass a string from Python to c++ (and changing the parameter to char* something is not and option)

PS Could I create a workaround like this?

  1. send the python string as c_char_p to C++ function that converts char* to std::string
  2. return the string or its pointer somehow???!! (how?) to python
  3. send it from python to HandleString function (but again I feel like I would have to change the parameter to string* here)

Upvotes: 6

Views: 9850

Answers (3)

heksbeks
heksbeks

Reputation: 21

Memory layout of std::string depends on the library, platform and architecture. The code below works for a 64bit DLL build with Visual C++ on Windows. If not working you need to adapt the StdString structure. Good luck!

def createStdStringObj(s):
    # Structure that represents the memory layout of std::string
    # that depends on library, platform and architecture used.
    # The layout works for a 64 bit DLL build with Visual C++
    # on Windows, adapt it if it is not working!
    class StdString(Structure):
        _fields_ = [
            ("data", c_char_p),         # Pointer to character data
            ("size", c_size_t),         # Size of the string
            ("capacity", c_size_t),     # Capacity of the string
        ]
    data = s.encode("utf-8")
    stds = StdString()
    stds.data = c_char_p(data)
    stds.size = len(data)
    stds.capacity = len(data)
    return stds

dllFcn(createStdStringObj('this is it'))

Upvotes: 2

James Kanze
James Kanze

Reputation: 153899

The Python C API converts Python str objects into char*, and there is an implicit conversion in C++ from char* (actually char const*) to std::string.

If the Python strings can contain null characters, you'll have to use PyString_AsStringAndSize to convert, and pass around the two values (the char* and the Py_ssize_t); there's an explicit conversion of these to std::string as well: std::string( pointer, length ).

Upvotes: 4

daramarak
daramarak

Reputation: 6145

Sounds like the simplest approach is to write a thin c++ wrapper around the library for the sole purpose of renegotiating the parameters from python into the more complex c++ classes.

Such an approach would also help remedy future problems of the same kind, without adding any real complexity to neither the python code or the c++ code.

Upvotes: 4

Related Questions