www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Binding non-trivial C++ structs

reply Paul O'Neil <redballoon36 gmail.com> writes:
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
Dec 16 2014
parent reply "Kagamin" <spam here.lot> writes:
previous thread: 
http://forum.dlang.org/post/mailman.1464.1415039051.9932.digitalmars-d puremagic.com
Dec 17 2014
parent Paul O'Neil <redballoon36 gmail.com> writes:
On 12/17/2014 03:01 AM, Kagamin wrote:
 previous thread:
 http://forum.dlang.org/post/mailman.1464.1415039051.9932.digitalmars-d puremagic.com
 
I read that thread. I don't understand if / how it answers this question. -- Paul O'Neil Github / IRC: todayman
Dec 17 2014