ncurses api with the D Programming Language

1.9k Views Asked by At

I am trying to teach myself AI using neural networks. Long story short, I wanted to create a simple graphic that would display what is happening in my program using ncurses. The tutorial that I am using is found here.

I was under the impression that D was compatible with C and I could theoretically call C functions relatively easily.

I find that not to be the case. I am a relatively novice programmer, so even the simplistic explanations are a little above my head. I found this here.

D is designed to fit comfortably with a C compiler for the target system. D makes up for not having its own VM by relying on the target environment's C runtime library. It would be senseless to attempt to port to D or write D wrappers for the vast array of C APIs available. How much easier it is to just call them directly.

This is done by matching the C compiler's data types, layouts, and function call/return sequences.

That sounds wonderful. A little bit over my head. I tested and got a simple C program working:

#include <curses.h>

int main(void) {
    int ch;

    initscr();
    noecho();
    cbreak();
    printw("Hit Ctrl+C to exit ...\n\n");
    for (;;) {
      ch = getch();
      printw("Value of char: %d (%02x)\n", ch, ch);
    }
    endwin();
    return 0;
}

shamelessly copied and pasted from another question on SO. At least I did my homework.

I tried basically the same thing from a simple D program. I got this error:

Error: module curses is in file 'curses.d' which cannot be read

I am absolutely positive that I am trying something really stupid.

Is there an easy way to use ncurses in a D program?

I'm running on zero sleep and caffeine, so please be gentle! Even a link to a website would be greatly appreciated!

I probably didn't include everything that I should have, so AMA.

And feel free to insult my intelligence.

4

There are 4 best solutions below

2
On BEST ANSWER

Ok, I feel I have been spamming a little, but I hope that all of the info will be useful in the future.

I found a project name ycurses. I discovered the problem with TLS is specific to D2. I changed the files to work with D2. dmd, gdc, it all works. I finally have my ncurses using D! It just took a long weekend of marathon coding and researching.

Since the code I found is old and appears to be abandoned, I am now hosting it on github

Even though the code states it will work with Tango, IT WILL NOT. I'll probably fix that some time this week.

The code has a nice little tutorial included, as well as instruction on how to link. Your welcome. I feel very accomplished all of a sudden.

0
On

Ok, there is a curses.d port? I don't know what to call it.. It is located here.

It still requires that you link against the ncurses library, but it works perfectly if you compile with the d1 dmd compiler. which seems to be kind of useless in my current project, so i've either got to port the files to d2 (not a bad idea, this project has long since been abandoned) or see if there is a way to link d1 compiles files, d2 compiled files and C. This would seem to me to be straight forward, but I also thought linking to C would be straightforward.

So after a few days and mostly trial-and-error style tests using files dated 7 years ago pulled from the internet, I finally got a simple hellp world compiled using the curses library.

I am strongly considering porting the dcurses files to D2 and hosting them myself... I just wish I had more experience with this type of thing...

4
On

Ok, after about 8 hours of digging through this crap I have determined that it is indeed possible to call C functions natively.

HOWEVER, it is also stated that "It would be senseless to attempt to port to D or write D wrappers for the vast array of C APIs available. How much easier it is to just call them directly."

Yeah, I'm going to call BS on that one. You DO have to port to D. Is it not considered porting when you are going from a macro enabled preprocessing .h file to a .d file? It is definitely nontrivial. So in my opinion they are intentionally leaving out the hard part and trying to make it look way better than it actually is.

In case anyone is wondering, If you have a C api that you would like to call in your D code: go grab the header file and attempt to convert it to something that D can read. Then simply compile your code, importing your new .d file, and linking it with whatever you are interfacing with. If you did it right, it'll work and you'll now have lots of memory leaks.

In my opinion, unless you need the entire library, save yourself a headache and just link a small C wrapper to your D code. You grab only what you need, and you have the added benefit of being able to rename stuff to whatever you want.

There are a couple of projects to help automate the process of translating header files. dtoh for windows only, and bcd which is found on dsource. bcd also includes bindings for curses! they are listed as being alpha only, but they seem to be working. I'm trying to call their curses.d file from my main.d file and I've been getting:

main.d:13: Error: cannot implicitly convert expression ("ype any character to see it in bold\x0a") of type string to char[]
main.d:15: Error: function aphrodite.curses.printw (char*,...) is not callable using argument types (char[])
main.d:15: Error: cannot implicitly convert expression (stuff) of type char[] to char*
main.d:20: Error: function aphrodite.curses.printw (char*,...) is not callable using argument types (string)
main.d:20: Error: cannot implicitly convert expression ("F1 Key pressed") of type string to char*
main.d:26: Error: function aphrodite.curses.printw (char*,...) is not callable using argument types (string)
main.d:26: Error: cannot implicitly convert expression ("The pressed key is ") of type string to char*
main.d:28: Error: function aphrodite.curses.printw (char*,...) is not callable using argument types (string,int)
main.d:28: Error: cannot implicitly convert expression ("%c") of type string to char*

so my problem lies in the way C handles strings and the way D handles strings. They don't match up and my extremely limited C knowledge doesn't tell me how to fix it. Luckily, for all the anti-documentation about calling C functions, there is quite a bit of info about how D types translate to C types.

I sincerely hope that someone finds this helpful somewhere down the line.

4
On

May I suggest having a look at Python? I know it's not D and is a completely different language but if your aim is to learn AI and don't insist on using D then Python is very good. It will allow you to do what you normally do in D in 1/10 of the time. ncurses in Python is an ease. I think there was some guy who wrote a tetris game in about 55 lines (which is standard).