Thread overview
Dynamically Loading a D DLL From a C Program in Linux
Oct 24, 2014
John McFarlane
Oct 24, 2014
John McFarlane
Oct 24, 2014
bachmeier
Oct 24, 2014
John McFarlane
Oct 25, 2014
MGW
October 24, 2014
I'm following the preliminary example "Dynamically Loading a D DLL From a C Program" here: http://dlang.org/dll-linux.html#dso9

Firstly, my output is different:

+main()
libdll.so is loaded
dll() function is found
dll()
unloading libdll.so
-main()

If looks like static this and ~this are not being called.

Secondly, when I replace printf with writeln, I get a seg fault. Trying to do just about anything beyond adding numbers and returning the result causes a similar crash.

I'm wondering whether D runtime is being initialized correctly. Can anyone suggest what I would do to ensure this? A more finalized example would be useful also.

DMD64 D Compiler v2.066.0
Ubuntu 10.04 64bit

Many thanks,
John
October 24, 2014
Apologies. That should be Ubuntu 14.04.

On Friday, 24 October 2014 at 20:59:20 UTC, John McFarlane wrote:
> I'm following the preliminary example "Dynamically Loading a D DLL From a C Program" here: http://dlang.org/dll-linux.html#dso9
>
> Firstly, my output is different:
>
> +main()
> libdll.so is loaded
> dll() function is found
> dll()
> unloading libdll.so
> -main()
>
> If looks like static this and ~this are not being called.
>
> Secondly, when I replace printf with writeln, I get a seg fault. Trying to do just about anything beyond adding numbers and returning the result causes a similar crash.
>
> I'm wondering whether D runtime is being initialized correctly. Can anyone suggest what I would do to ensure this? A more finalized example would be useful also.
>
> DMD64 D Compiler v2.066.0
> Ubuntu 10.04 64bit
>
> Many thanks,
> John

October 24, 2014
I can't answer the first question, but for the second, I've given an example here:

http://forum.dlang.org/post/zfdvrwvgavykauczbreq@forum.dlang.org

I've done that many, many times and do not see any problems related to the runtime.

On Friday, 24 October 2014 at 20:59:20 UTC, John McFarlane wrote:
> I'm following the preliminary example "Dynamically Loading a D DLL From a C Program" here: http://dlang.org/dll-linux.html#dso9
>
> Firstly, my output is different:
>
> +main()
> libdll.so is loaded
> dll() function is found
> dll()
> unloading libdll.so
> -main()
>
> If looks like static this and ~this are not being called.
>
> Secondly, when I replace printf with writeln, I get a seg fault. Trying to do just about anything beyond adding numbers and returning the result causes a similar crash.
>
> I'm wondering whether D runtime is being initialized correctly. Can anyone suggest what I would do to ensure this? A more finalized example would be useful also.
>
> DMD64 D Compiler v2.066.0
> Ubuntu 10.04 64bit
>
> Many thanks,
> John

October 24, 2014
On Friday, 24 October 2014 at 22:33:09 UTC, bachmeier wrote:
> I can't answer the first question, but for the second, I've given an example here:
>
> http://forum.dlang.org/post/zfdvrwvgavykauczbreq@forum.dlang.org
>
> I've done that many, many times and do not see any problems related to the runtime.
>
> On Friday, 24 October 2014 at 20:59:20 UTC, John McFarlane wrote:
>> I'm following the preliminary example "Dynamically Loading a D DLL From a C Program" here: http://dlang.org/dll-linux.html#dso9
>>
>> Firstly, my output is different:
>>
>> +main()
>> libdll.so is loaded
>> dll() function is found
>> dll()
>> unloading libdll.so
>> -main()
>>
>> If looks like static this and ~this are not being called.
>>
>> Secondly, when I replace printf with writeln, I get a seg fault. Trying to do just about anything beyond adding numbers and returning the result causes a similar crash.
>>
>> I'm wondering whether D runtime is being initialized correctly. Can anyone suggest what I would do to ensure this? A more finalized example would be useful also.
>>
>> DMD64 D Compiler v2.066.0
>> Ubuntu 10.04 64bit
>>
>> Many thanks,
>> John

Thanks. That gets me a lot futher.
October 25, 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;
}