www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Dynamically Loading a D DLL From a C Program in Linux

reply "John McFarlane" <dlang john.mcfarlane.name> writes:
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
Oct 24 2014
next sibling parent "John McFarlane" <dlang john.mcfarlane.name> writes:
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
Oct 24 2014
prev sibling parent reply "bachmeier" <no spam.net> writes:
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
Oct 24 2014
parent reply "John McFarlane" <dlang john.mcfarlane.name> writes:
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.
Oct 24 2014
parent "MGW" <mgw yandex.ru> writes:
// 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;
}
Oct 25 2014