D

Difference between version 40 and 41 - Previous - Next
The '''[http://dlang.org/%|%D]''' programming language is designed as an evolution of [C]/[C++].
  

** Documentation **

   [http://en.wikipedia.org/wiki/D_%28programming_language%29%|%Wikipedia]:   

   [http://wiki.dlang.org/%|%official wiki]:   

   [http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage%|%old wiki]:   

   [http://dlang.org/comparison.html%|%Feature Matrix]:   

** Tools **

   [http://gdcproject.org/%|%GDC]:   an open-source D compiler for [GCC]

   [http://wiki.dlang.org/LDC%|%LDC]:   an open-source D compiler based on [LLVM]
   [https://fcorumde.dlang.org/threpad/wdddgiowaidcojbrklsg@forum.dlang.orges/tkd%|%Tkd] v1.01.0-beta,13 20149-056-0413:   

** See also **

   [Example of a Tcl extension in D] (D2):   


** Examples **

*** Pat Thoyts' example (D1) ***

It is fairly simple to call [Tcl] from D. In fact, it looks a ''lot'' like [C++] in most places. The main issue is to generate an import symbol file for the [Tcl C API%|%Tcl API], which can be done by using the genStubs script file.

Under [Microsoft Windows] I had to convert the standard [ActiveTcl] tcl83.lib to an OMF format library.
To do this we convert to COFF format using [Microsoft%|%Microsoft's] [http://msdn.microsoft.com/en-us/library/y0zzbyt4.aspx%|%LINK] program and then Digital Mars' COFF2OMF utility

======none
link /lib /convert tcl83.lib
coff2omd tcl83.lib
======

To illustrate, here is an initial stab. Build this using

======none
dmd simple.d tcl83.lib  (Using Windows)
======

or

======none
dmd simple.d -L-ltcl    (Using UNIX)
======

======
// simple.d - Copyright (C) 2003 Pat Thoyts <[email protected]>
//
// Demonstrate linking to Tcl from the D programming language. 
// See http://dlang.org/ for information
// about ``D''
//
// $Id: 6261,v 1.28 2006-11-20 19:00:16 jcw Exp $

import std.stream;
import std.string;
import std.compiler;

// ----------------------------------------------------------------------
// Define the bits we need for interfacing to Tcl API
//
extern (C) {
   alias void* ClientData;
   alias void (*Tcl_FreeProc)(char* blockPtr);
   alias void (*Tcl_CmdDeleteProc)(ClientData clientData);
   alias int (*Tcl_CmdProc)(ClientData clientData, Tcl_Interp* interp,
                            int argc, char* argv[]);
   alias void* Tcl_Command;

   struct Tcl_Interp {
      char* result;
      Tcl_FreeProc blockPtr;
      int errorLine;
   }

   enum {
      TCL_OK       = 0,
      TCL_ERROR    = 1,
      TCL_RETURN   = 2,
      TCL_BREAK    = 3,
      TCL_CONTINUE = 4,
   }

   const Tcl_FreeProc TCL_VOLATILE = cast(Tcl_FreeProc)1;
   const Tcl_FreeProc TCL_STATIC   = cast(Tcl_FreeProc)0;
   const Tcl_FreeProc TCL_DYNAMIC  = cast(Tcl_FreeProc)3;

   Tcl_Interp* Tcl_CreateInterp();
   Tcl_Command Tcl_CreateCommand(Tcl_Interp* interp, char* cmdName,
                                      Tcl_CmdProc proc,
                                 ClientData clientData,
                                 Tcl_CmdDeleteProc deleteProc);
   int   Tcl_Eval           (Tcl_Interp* interp, char* string);
   int   Tcl_EvalFile       (Tcl_Interp* interp, char* fileName);
   char* Tcl_GetStringResult(Tcl_Interp* interp);
   void  Tcl_SetResult      (Tcl_Interp* interp, char* str,
                              Tcl_FreeProc freeProc);
}

// ----------------------------------------------------------------------
int main(char[][] args)
{
   Tcl_Interp* interp = Tcl_CreateInterp();

   Tcl_CreateCommand(interp, "ddemo", &DDemoCmd,
                     null, null);

   int r;
   if( args.length < 2 )
   {
      r = Tcl_Eval(interp, "puts \"Tcl version: [info tcl]\"; ddemo");
   }
   else
   {
      r = Tcl_EvalFile(interp, args[1]);
   }
   printf(Tcl_GetStringResult(interp));
   return r;
}

// Add a new command to the Tcl interpreter.
// In this case: return some information about the D compiler.
extern (C):
int 
DDemoCmd(ClientData clientData, Tcl_Interp *interp, int argc, char* argv[])
{
   MemoryStream stm = new MemoryStream;
   stm.printf(std.compiler.name);
   stm.printf(" %d.%d", std.compiler.version_major, std.compiler.version_minor);
   Tcl_SetResult(interp, toStringz(stm.toString()), TCL_STATIC);
   return TCL_OK;
}

// ----------------------------------------------------------------------
//
// Local variables:
//   mode: c
//   compile-command: "dmd simple.d tcl83.lib"
//   cygwin: "gdc simple.d -ltcl"
// End:
======

*** nedbrek's example (D1) ***

nedbrek - I've updated the code for a later D compiler (cygming special, gdc 0.24, using dmd 1.020).
You can then extract the Tcl declarations into a separate file (call it 'tcl.d').  To create an extension for Tcl, called 'test', put this in a file 'test.d':

======none
import std.compiler;
import std.stream;
import std.string;
import std.c.windows.windows;
import tcl;

HINSTANCE g_hInst;

extern (C)
{
    void gc_init();
    void gc_term();
    void _moduleCtor();
}

extern (Windows)
BOOL DllMain(HINSTANCE hinst, ULONG reason, LPVOID rsvd)
{
    switch( reason )
    {
    case DLL_PROCESS_ATTACH:
        gc_init();
        _moduleCtor();
        break;
 
    case DLL_PROCESS_DETACH:
        gc_term();
        break;

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        return FALSE;
    }
    g_hInst = hinst;
 
    return TRUE;
}

extern (C)
int Test_Init(Tcl_Interp* interp)
{
    Tcl_CreateCommand(interp, "ddemo", &DDemoCmd, null, null);
    return TCL_OK;
}

extern (C)
int DDemoCmd(ClientData clientData, Tcl_Interp *interp, int argc, char* argv[])
{
    auto stm = new MemoryStream;
    stm.printf(std.compiler.name);
    stm.printf(" %d.%d", std.compiler.version_major,
               std.compiler.version_minor);
    Tcl_SetResult(interp, toStringz(stm.toString()), TCL_STATIC);
 
    return TCL_OK;
}
======

This can be built with:

======none
gdc -shared -otest.so test.d -ltcl
======

It then works like a regular tcl extension:

======none
$ tclsh
% load test.so
% ddemo
======

** Discussion **

[SYStems]: I would say C not used more because of competition, D is trying to compete a pretty saturated market.
   * For the open source croud, it will compete with C, C++, Java, possibly C# (mono and stuff)
   * For the commercial croud, it's mainly Java and C# and possibly C/C++
   * For somekind of croud, it's Haskell, OCaml, Scheme etc ...
   * For the looking for fun new languages to learn croud it's JavaScript (because of AJAX), Ruby, Perl 6 and Tcl 8.5 OO new features ;)
Those in my opinion are the market segments where D may compete and as I suggest they are saturated

----

As of October 2006, D is on the verge of being listed with [Languages with a Tk binding]

[http://lists.puremagic.com/pipermail/digitalmars-d/2006-October/008776.html].

[RLH]: That isn't how I read that thread.

[LWV]: After reading through the thread a bit, I see
http://www.algonet.se/~afb/d/TK.zip is a beginning of a binding between
D and Tk. Some of the issues are people wanting a D GUI that is
designed with D philosophies, and later in the thread, concern about
the fact that Tk requires X11 headers in some cases. I do not get the feeling
that the D community itself is embracing Tk. Instead, there appears to be a 
number of people thinking about the possibility, with a larger number looking
at alternatives.

-----
[https://github.com/nomad-software/tcltk%|%Bindings to Tcl/Tk for the D programming language]

<<categories>> Language | Object Orientation