// MGW 05.01.14
// We model in D object C ++ QByteArray from Qt.
//--------------------------------------------
// Windows: dmd st1.d
//   Linux: dmd st1.d -L-ldl

import core.runtime;     // Load DLL for Win
import std.stdio;        // writeln

version(linux) {
    import core.sys.posix.dlfcn;  // declare dlopen() и dlsym()

// On Linux these functions are not defined in core.runtime, here and it was necessary to add. extern (C) void* rt_loadLibrary(const char* name) { return dlopen(name, RTLD_GLOBAL || RTLD_LAZY); } void* GetProcAddress(void* hLib, string nameFun) { return dlsym(hLib, nameFun.ptr); }
}
version(Windows) {
        import std.c.windows.windows;  // GetProcAddress для Windows
}
//it is important!!!
//At definition constructs and functions of members the attribute "extern (C)" is obligatory! alias extern (C) void function(void*, char*) t_QByteArray_QByteArray; t_QByteArray_QByteArray QByteArray_QByteArray; alias extern (C) void* function(void*, char, int) t_QByteArray_fill; t_QByteArray_fill QByteArray_fill;

// Struct QByteArray from qbytearray.h in include directory.
// inline char *QByteArray::data() { detach(); return d->data; } где d есть Data*
struct Data {
        void* rref;
        int   alloc;
        int   size;
char* data; // Here actually behind what it is necessary for us, the index on a file of bytes
        char  array[1];
}

// == Experimental class DQByteArray ==
class DQByteArray {
Data* QtObj; // Object: &QtObj - its size of 4 bytes (32 digit version)
    // ------------------
    // class D, call class C++
    this(char* buf) {
        QByteArray_QByteArray(&QtObj, buf);
    }
    ~this() {
// It is possible to find ~this and here it to register, but it is routine....
    }
// inline char *QByteArray::data() { detach(); return d->data; } где d есть Data*
    char* data() {
        return (*QtObj).data;
    }
// D: Data** ==> C++: QByteArray Here also it became clear, that such object With ++, looking at it from D
    void* fill(char ch, int resize=-1) {
        return QByteArray_fill(&QtObj, ch, resize);
    }
}

int main(string[] args) {

// Files with QByteArray C++
version(linux)   {    auto nameQtCore = "libQtCore.so";  }
version(Windows) {    auto nameQtCore = "QtCore4.dll";   }

    auto h = Runtime.loadLibrary(nameQtCore); // Load dll или so

    // It is QByteArray::QByteArray(char*);
QByteArray_QByteArray = cast(t_QByteArray_QByteArray)GetProcAddress(h, "_ZN10QByteArrayC1EPKc");
    // QByteArray::fill(char*, int);
QByteArray_fill = cast(t_QByteArray_fill)GetProcAddress(h, "_ZN10QByteArray4fillEci");

    // Create my class
    DQByteArray ba = new DQByteArray(cast(char*)"ABC".ptr);
    printf("\n ba.data() = %s", ba.data());

    // Test fill() from C++
    ba.fill('Z', 5);
    printf("\n ba.data() = %s", ba.data());

    return 0;
}

Reply via email to