comp.lang.ada
 help / color / mirror / Atom feed
* Please evaluate tiny binding that does not use Interfaces.C
@ 2017-08-18  2:23 patrick
  2017-08-18  5:18 ` Per Sandberg
  0 siblings, 1 reply; 4+ messages in thread
From: patrick @ 2017-08-18  2:23 UTC (permalink / raw)


Hi Everyone

It seems like everyone uses Interfaces.C when creating a C binding. I realize that this makes the binding more portable.

However, is there something to be said for small, easy to read code too?

It seems that most bindings attempt to recreate C structs with records and then create pointers to those records. Meanwhile, the binding does not access any members of that C struct directly. Those structs often have other structs as members too and the process goes on and on.

I realize that void pointers are dangerous but C is dangerous and I am wondering if my use is within good practices?

My code is small and contains no exception handling and likely has lots of other things missing like a gpr files and such but is the basic interfacing between C and Ada okay? Do you see any pitfalls, aside from the fact that it is calling C ?

I personally find this very easy to write and read, I am hoping that this will work out. Please let me know what you think

-----------------------------------------------------------------
build.sh

gnatmake -c terminal_app.adb 
gnatmake -c ncurses_glue

gcc-4.6 -c ncurses_glue.c 

gnatbind terminal_app.ali ncurses_glue.ali

gnatmake -c b~terminal_app.adb 
gcc-4.6 terminal_app.o  b~terminal_app.o ncurses_glue.o -o terminal_app  -gnatwa -lncursesw -lgnat -gnato

-----------------------------------------------------------------
      -- test to see if library without interfaces.c will work out
      --
      --
         with ncurses_glue ;
         with ada.strings.fixed ;
         
         procedure terminal_app is
 
         package ng renames ncurses_glue ;
         package sf renames ada.strings.fixed ;
 
         stdscr : access ng.WINDOW ;
         ret    : integer ;
         str    : string := "test 㐴    " & ASCII.NUL ;
 
         begin

          stdscr := ng.initscr_plus ;
          ret    := ng.addstr(str) ;
          ret    := ng.refresh ;
          delay 2.0 ;
          ret    := ng.endwin ;

         end terminal_app ;

-----------------------------------------------------------------

         package ncurses_glue is

         type null_record is null record ;

         type WINDOW is access null_record ;

         function initscr_plus
                  return Access WINDOW;
                  pragma Import (C, initscr_plus, "initscr_plus");

         function addstr (arg1 : string)
                  return integer ;
                  pragma Import (C, addstr, "addstr");

         function refresh
                  return integer;
                  pragma Import (C, refresh, "refresh") ;

         function endwin
                  return integer;
                  pragma Import (C, endwin, "endwin") ;

         end ncurses_glue ;
-----------------------------------------------------------------
#include <ncursesw/ncurses.h>
#include <locale.h>

void * initscr_plus() {
  setlocale(LC_CTYPE,"");
  initscr() ;
  return stdscr ;
 }

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Please evaluate tiny binding that does not use Interfaces.C
  2017-08-18  2:23 Please evaluate tiny binding that does not use Interfaces.C patrick
@ 2017-08-18  5:18 ` Per Sandberg
  2017-08-18 13:05   ` patrick
  0 siblings, 1 reply; 4+ messages in thread
From: Per Sandberg @ 2017-08-18  5:18 UTC (permalink / raw)


Hi

The proper way to generate bindings to libraries with interfaces defined 
in C/C++ is to use the compiler-switch -fdump-ada-spec. To trust a human 
to get all the bits and pieces correct only works if the interface is 
trivial.
The way I usually does it is:

* generate valid a C/C++ file including all required headers.
* compile the file with gcc -c -fdfump-ada-spec ${file}
* If required, edit in the file using some script tool such as sed.

By using the above method you could regenerate the bindings when the 
underlying library evolves and you will get a correct binding every time.

Of corse if you want to use one and only one simple method from a 
foreign library its always possible to just do a simple "import" in the 
code.

/P

Den 2017-08-18 kl. 04:23, skrev patrick@spellingbeewinnars.org:
> Hi Everyone
> 
> It seems like everyone uses Interfaces.C when creating a C binding. I realize that this makes the binding more portable.
> 
> However, is there something to be said for small, easy to read code too?
> 
> It seems that most bindings attempt to recreate C structs with records and then create pointers to those records. Meanwhile, the binding does not access any members of that C struct directly. Those structs often have other structs as members too and the process goes on and on.
> 
> I realize that void pointers are dangerous but C is dangerous and I am wondering if my use is within good practices?
> 
> My code is small and contains no exception handling and likely has lots of other things missing like a gpr files and such but is the basic interfacing between C and Ada okay? Do you see any pitfalls, aside from the fact that it is calling C ?
> 
> I personally find this very easy to write and read, I am hoping that this will work out. Please let me know what you think
> 
> -----------------------------------------------------------------
> build.sh
> 
> gnatmake -c terminal_app.adb
> gnatmake -c ncurses_glue
> 
> gcc-4.6 -c ncurses_glue.c
> 
> gnatbind terminal_app.ali ncurses_glue.ali
> 
> gnatmake -c b~terminal_app.adb
> gcc-4.6 terminal_app.o  b~terminal_app.o ncurses_glue.o -o terminal_app  -gnatwa -lncursesw -lgnat -gnato
> 
> -----------------------------------------------------------------
>        -- test to see if library without interfaces.c will work out
>        --
>        --
>           with ncurses_glue ;
>           with ada.strings.fixed ;
>           
>           procedure terminal_app is
>   
>           package ng renames ncurses_glue ;
>           package sf renames ada.strings.fixed ;
>   
>           stdscr : access ng.WINDOW ;
>           ret    : integer ;
>           str    : string := "test 㐴    " & ASCII.NUL ;
>   
>           begin
> 
>            stdscr := ng.initscr_plus ;
>            ret    := ng.addstr(str) ;
>            ret    := ng.refresh ;
>            delay 2.0 ;
>            ret    := ng.endwin ;
> 
>           end terminal_app ;
> 
> -----------------------------------------------------------------
> 
>           package ncurses_glue is
> 
>           type null_record is null record ;
> 
>           type WINDOW is access null_record ;
> 
>           function initscr_plus
>                    return Access WINDOW;
>                    pragma Import (C, initscr_plus, "initscr_plus");
> 
>           function addstr (arg1 : string)
>                    return integer ;
>                    pragma Import (C, addstr, "addstr");
> 
>           function refresh
>                    return integer;
>                    pragma Import (C, refresh, "refresh") ;
> 
>           function endwin
>                    return integer;
>                    pragma Import (C, endwin, "endwin") ;
> 
>           end ncurses_glue ;
> -----------------------------------------------------------------
> #include <ncursesw/ncurses.h>
> #include <locale.h>
> 
> void * initscr_plus() {
>    setlocale(LC_CTYPE,"");
>    initscr() ;
>    return stdscr ;
>   }
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Please evaluate tiny binding that does not use Interfaces.C
  2017-08-18  5:18 ` Per Sandberg
@ 2017-08-18 13:05   ` patrick
  2017-08-18 15:41     ` patrick
  0 siblings, 1 reply; 4+ messages in thread
From: patrick @ 2017-08-18 13:05 UTC (permalink / raw)


Hi Per

Thanks for answering my post!

Do you like friendly debates? If we were in the same room you would see that I have a smile on my face and I am not trying to be argumentative or hostile in any way, it's just that I seem to be thinking differently then most Ada people right now and I would love to have my sanity checked. Please don't be offended by this, please help me test my logic......

Here is some background.

I bought/printed 53 lbs of Ada books in 2012. I studied every night. I basically failed. I wanted to use Ada instead of C but every where i turned I needed a binding to C. GTK-Ada was very confusing and I struggled badly with it and eventually gave up on Ada.

I actually went to GnuCOBOL(call open-cobol as the time). I loved it and still do. I learned a lot more about C and I have had a great time mixing GnuCOBOL and C.

I have come back to Ada a few times. I used Interfaces.COBOL. I can use it well but the code required to blend COBOL and Ada is IMHO as gross as the code to mix C and Ada, when using Intefaces.C.

I have read extensively about Interfaces.C and Interfaces.C. Most examples will use some simple C target. In reality people will often want to interface with massive C/C++ libraries.

I know it would be nice if all Ada bindings were thick but is it not in fact fair to say that most are thin, we don't have large communities to support them and to look for bugs, we don't have many bindings relative to let's say Python and writing good Ada bindings is non-trivial to begin with.

My feeling right now is that the expertise needed to use bindings like GTK-Ada is of such a high degree that the programmer might just be better off studying C and writing shim code to that C and binding to it or directly to the C library on an as-needed basis rather then trying to write a whole binding to share with the community.

I am really sorry for writing the above, I know how hard it is to write a binding and I don't want to discourage people but I think it's also important to speak honestly about the language, I think lots of people stop by to see what it's about but move on. I think if it was easier to interface with other languages, Ada could start off as library code to support other languages at first and then could win over people's hearts and become more central or in fact "the" central language of the given application.

With the approach taken above, I am sure I can interface with COBOL without having actually tried this but what about other ELF compatible languages from GCC or elsewhere, this would open the door to interfacing with Java and Objective-C. Lots of languages have C interfaces or compile to intermediate C. Ada could be mixed with Haskell, Vala or dozens more.

I remember back in 2012 being to desperate to have -fdump-ada-spec that I switched distros. I remember using it inn stupid ways, like running it on the whole C library not just the header and trying to bind to internal functions and such.

In almost all cases Interfaces.C isn't doing anything but to someone that was struggling like I was, it adds a layer of magic that hides a much simpler truth.

I also question -fdump's decisions. As per the first post, why recreate a C struct and all of it's nested structs only to create a pointer of the correct type? Yes void pointers are dangerous but mountains of code that do not need to be there is also dangerous.

Simple short code is easier to debug and maintain and a lack of maintenance or worse yet, a poor understanding of code is IMHO worse than the danger of a void pointer.

Why use Interfaces.X if Ada already has the built in types to interface. Having to cast back and forth only makes for more code and less code clarity and at the end of the day, we are still calling into C and more code to check for actual C dangers seems like a better idea to me than using Interfaces.X which offers no protection anyways.

Thanks for reading


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Please evaluate tiny binding that does not use Interfaces.C
  2017-08-18 13:05   ` patrick
@ 2017-08-18 15:41     ` patrick
  0 siblings, 0 replies; 4+ messages in thread
From: patrick @ 2017-08-18 15:41 UTC (permalink / raw)


Sorry for answering my own post. I just wanted to add that in the above example WINDOW is a pointer to a null record but it is not really a null pointer. I would not be able to pass other pointer types to functions expecting WINDOW so is it not type safe in fact?

Why create records to match C structs, a pointer declared of that type can only be used to pass addresses of that struct's type and accomplishes the same thing with far less clutter no?

Have we all been giving -fdump-ada-spec a free pass without evaluating it's logic or am I the one being illogical ?




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-08-18 15:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-18  2:23 Please evaluate tiny binding that does not use Interfaces.C patrick
2017-08-18  5:18 ` Per Sandberg
2017-08-18 13:05   ` patrick
2017-08-18 15:41     ` patrick

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox