Skip to content

Instantly share code, notes, and snippets.

@hcho3
Last active November 14, 2018 05:24
Show Gist options
  • Save hcho3/1c65ad2927a06abc02b9f3332e6c0307 to your computer and use it in GitHub Desktop.
Save hcho3/1c65ad2927a06abc02b9f3332e6c0307 to your computer and use it in GitHub Desktop.
Borrowing C++ string into Python safely
#include <string>
class Foo {
public:
Foo() : bar("foobar") {}
std::string bar;
};
extern "C" void CreateFoo(void** handle) {
*handle = static_cast<void*>(new Foo());
}
extern "C" void FooGetContent(void* handle, const char** out) {
*out = static_cast<Foo*>(handle)->bar.c_str();
}
extern "C" void FooChangeContent(void* handle) {
static_cast<Foo*>(handle)->bar = "meow";
}
import ctypes
lib = ctypes.cdll.LoadLibrary('./test.dylib')
foo = ctypes.c_void_p()
lib.CreateFoo(ctypes.byref(foo))
val = ctypes.c_char_p() # borrowed pointer from C++
lib.FooGetContent(foo, ctypes.byref(val))
val2 = val.value.decode('utf-8') # this makes a copy
print(val.value)
print(val2)
lib.FooChangeContent(foo)
print(val.value) # this pointer now refers to "meow"
print(val2) # this value is still "foobar"
@hcho3
Copy link
Author

hcho3 commented Nov 14, 2018

It's okay to borrow const char* from C++, as long as we call .decode() right away from the Python side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment