Binding non-trivial C++ structs
    Paul O'Neil via Digitalmars-d-learn 
    digitalmars-d-learn at puremagic.com
       
    Tue Dec 16 17:49:54 PST 2014
    
    
  
To make my C++ binding life easier, I wrote a small string structure [1]
in C++ to use instead of std::string and produced the D declarations for
some of it [2].  (It's not that complicated, I promise.)  The important
properties of this struct are that it has a non-trivial copy constructor
and a destructor.  These properties mean that the ABI for returning a
binding::string are different than just a plain value [3].  Calling a
C++ function from D that returns a string does not obey the changed ABI.
How do I indicate to dmd that the C++ string should have the different
ABI?  Well I should add a copy constructor or destructor, right?  Copy
constructors on structs don't exist because we have blitting, so I can't
do that.  When I add a destructor, linking fails with:
undefined reference to `_D6binding6binding6string6__dtorMFZv'
So that doesn't work either.
Now for the questions:
1) Is this supported?
2) If so, how do I actually do it?
Thanks
Paul O'Neil
[1] C++:
namespace binding {
class string
{
    char * buffer;
    size_t length;
    public:
    string();
    string(const string& other);
    string(string&&);
    string(const char * str);
    string(const char * str, unsigned long len);
    string(const char * start, const char * end);
    string(size_t len);
    ~string();
    size_t size();
    char * begin();
    char * end();
    bool operator==(const string& other) const;
    bool operator!=(const string& other) const;
    const char * c_str();
    const char * c_str() const;
    string operator+(const string& other) const;
    string& operator=(const string& other);
    string& operator=(string&& other);
    void operator+=(const string& other);
};
}
[2] D:
extern(C++, binding) struct string
{
    private char * buffer;
    private size_t length;
    public size_t size();
    public char * begin();
    public char * end();
    public char * begin();
    public char * end();
    public char * c_str();
    this(ref const(binding.string));
    this(const(char)* str);
    this(const(char)* str, size_t len);
    this(const(char)* start, const(char)* end);
    this(size_t len);
    this(ref const(binding.string));
    ~this();
}
[3] http://mentorembedded.github.io/cxx-abi/abi.html#normal-call
-- 
Paul O'Neil
Github / IRC: todayman
    
    
More information about the Digitalmars-d-learn
mailing list