I am encountering some sporadic crashes when calling into a C++ library (not under my control) from C#.
The internal code of the C++ library is roughly like this:
#include <string>
#include <memory>
class Holder {
public:
static std::shared_ptr<Holder> create() {
return std::make_shared<Holder>();
}
const std::string& getRef() {
return value;
}
private:
std::string value;
};
extern "C" void getRef(std::string& v) {
auto h = Holder::create();
v = h->getRef();
}
getRef is called from C# via P/invoke with no special marshalling.
Is this guaranteed to work? h goes out of scope at the end of getRef, but a reference to its member value is held and passed on. Is this reference still valid when being access on the C# side?
The C++ part is fine.
v = h->getRef();getRefreturns a reference to a string that will be valid untilhis killed off, which happens at the end of the function. However, the string is copied into thevstring in this line, so no problem.That's where you are wrong; that reference is not passed on to anything.
EDIT: concerning the comments that this doesn't copy anything, try this:
Basically, while a reference is functionally similar to a pointer, it can't be assigned to: if you assign to a reference, you're always assigning to the object that's being referenced.