digitalmars.D.learn - Creating Libraries Callable from C
- TJB (13/13) Apr 26 2014 Is it possible to write a library that is callable from C without
- =?UTF-8?B?UsOpbXkgTW91w6t6YQ==?= (78/90) Apr 26 2014 It is possible to write a D library useable from C. However, we may not
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (9/16) Apr 26 2014 And if those functions are called from the library's own initialization
- ketmar (2/9) Apr 26 2014 and what if user links two such libraries? ;-)
Is it possible to write a library that is callable from C without the enduser even knowing it was written in D? That is, can a C programmer use the library as though it were written in C straightforwardly? Or for that matter, by an enduser programming in Python or Lua where the library is being exposed through those languages' C API? I'm sure this is a widely discussed and well understood topic, but I am a newbie (and have no formal training in CS) and don't know where to look for documentation. A little baby tutorial would be super helpful and well received by this newbie. Thanks so much! TJB
Apr 26 2014
It is possible to write a D library useable from C. However, we may not be able to hide the fact that the library has been written in D. You must first export some D function you want to use from C, using extern (C) declaration. Then declare them in your C program or headers. You will also have to declare 2 function for initializing and terminating D's runtime: char rt_init(long long); char rt_term(long long); call rt_init(0) before using your D functions (this will initialize D runtime - the D GC amongst other things), then use rt_term(0) at the end of the program - you may want to register an exit function with atexit(). With older versions of DMD we had also to create a D module with an empty main() function that had to be linked with the C program to force the D compiler to generate some symbols that were not generated within the object files. As of dmd 2.064, this is no longer necessary. Below is an example I once retrieve from this newsgroup: dlibrary.d ========== import std.stdio, std.array, std.range; extern(C) void printf(in char*,...); extern(C) void funcD(){ printf("C's printf in D\n"); writeln("D's writeln"); writeln("D's array alloc: ", new double[3]); writeln("D's iota: ", iota(0, 30, 4)); } cmain.c ======= int printf(char*, ...); void funcC() { printf("C's printf in C\n"); } char rt_init(long long); char rt_term(long long); void main(){ // code without D funcC(); rt_init(0); // initialize D's runtime //code with D funcD(); rt_term(0); // terminate D's runtime //code without D } Compilation =========== Compiling the D library ----------------------- dmd -c dlibrary.d Compiling the C executable -------------------------- You can do it with either dmd or gcc gcc -o cmain cmain.c dlibrary.o \ -m32 -lrt -lphobos2 -lpthread -lm \ -Xlinker -L$DMD/linux/lib32 \ -Xlinker --no-warn-search-mismatch \ -Xlinker --export-dynamic To get the proper gcc flags, use dmd in verbose mode: - first compile cmain: gcc -c cmain.c - then: dmd -v cmain.o dlibrary.o Executing --------- ./cmain C's printf in C C's printf in D D's writeln D's array alloc: [nan, nan, nan] D's iota: [0, 4, 8, 12, 16, 20, 24, 28] D from other programming languages ================================== There is a project to write python extensions in D PYD: https://bitbucket.org/ariovistus/pyd I also wrote about my experiment of using Swig for a proof of concept PHP extension in D: http://forum.dlang.org/post/gwqstgaiivknieyqfseu forum.dlang.org What works for PHP can work for the other Swig supported languages On 04/26/2014 07:13 PM, TJB wrote:Is it possible to write a library that is callable from C without the enduser even knowing it was written in D? That is, can a C programmer use the library as though it were written in C straightforwardly? Or for that matter, by an enduser programming in Python or Lua where the library is being exposed through those languages' C API? I'm sure this is a widely discussed and well understood topic, but I am a newbie (and have no formal training in CS) and don't know where to look for documentation. A little baby tutorial would be super helpful and well received by this newbie. Thanks so much! TJB
Apr 26 2014
On 04/26/2014 11:27 AM, Rémy Mouëza wrote:You will also have to declare 2 function for initializing and terminating D's runtime: char rt_init(long long); char rt_term(long long); call rt_init(0) before using your D functions (this will initialize D runtime - the D GC amongst other things), then use rt_term(0) at the end of the program - you may want to register an exit function with atexit().And if those functions are called from the library's own initialization and deinitialization functions, the C program need not know anything about the D runtime dependence: void mylib_init() { rt_init(0); // ... other initialization } Ali
Apr 26 2014
On Sunday, 27 April 2014 at 02:15:59 UTC, Ali Çehreli wrote:And if those functions are called from the library's own initialization and deinitialization functions, the C program need not know anything about the D runtime dependence: void mylib_init() { rt_init(0); // ... other initialization }and what if user links two such libraries? ;-)
Apr 26 2014