On Sunday, 12 January 2014 at 16:17:23 UTC, MGW wrote:
Maybe this will be useful in the work:
Compile
Windows: dmd st1.d
Linux: dmd st1.d -L-ldl
// ---------------------------------------
// MGW 05.01.14
// Model in D a C++ object QByteArray of Qt.
//--------------------------------------------
import core.runtime; // Load DLL for Win
import std.stdio; // writeln
version(linux) {
import core.sys.posix.dlfcn; // define dlopen() и dlsym()
// On Linux DMD v2.063.2, these functions are not defined
in core.runtime, so I had to write to.
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 for Windows
}
// Warning!!!
// When defining constructors and member functions attribute
"extern (C)" required!
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;
//T he structure of the QByteArray from the file qbytearray.h
in the include directory. Because C++ inline functions missing
in DLL
// there is no possibility to directly call a dozen functions.
// If you look in C++ there definition is as follows:
// inline char *QByteArray::data() { detach(); return d->data;
} where d is the Data*
struct Data {
void* rref;
int alloc;
int size;
char* data; // That's what we need, a pointer to
an array of bytes
char array[1];
}
// == Experimental class DQByteArray ==
class DQByteArray {
Data* QtObj; // this is object: &QtObj - size 4 byte
(32 os)
// ------------------
// constructor D called of a constructor C++
this(char* buf) {
QByteArray_QByteArray(&QtObj, buf);
}
~this() {
// I can find a destructor, and here his record, but
too lazy to do it ....
}
// As inline function is not stored in a DLL have to model
it through the structure of the Data
char* data() {
return (*QtObj).data;
}
// D format: Data** == C++ format: QByteArray
// so it became clear that such a C++object, looking at it
from the D
void* fill(char ch, int resize=-1) {
return QByteArray_fill(&QtObj, ch, resize);
}
}
int main(string[] args) {
// These files get QByteArray C++
version(linux) { auto nameQtCore = "libQtCore.so"; }
version(Windows) { auto nameQtCore = "QtCore4.dll"; }
auto h = Runtime.loadLibrary(nameQtCore); // Loading dll or
so
// Load function constructor 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");
// QByteArray::~QByteArray()
// Create our experimental subject and consider its data
DQByteArray ba = new DQByteArray(cast(char*)"ABC".ptr);
printf("\n ba.data() = %s", ba.data());
// Experience the action of the fill() and see the result
ba.fill('Z', 5);
printf("\n ba.data() = %s", ba.data());
return 0;
}
Hi yes I think noticed in another thread that you were wrapping
Qt with dynamic loading of the qt libs, interesting idea - does
your code allow subclassing of the Qt classes and overriding the
virtual methods? I'm taking a much more traditional approach, but
there is method in my madness :-)