Dynamically Loading a D DLL From a C Program in Linux
MGW via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Oct 25 04:53:20 PDT 2014
// 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;
}
More information about the Digitalmars-d-learn
mailing list