Domanda

I found http://support.zeus.com/zws/examples/2005/12/16/hello_world_in_perl_and_c and this two examples are working.

Now I tried this for Ada and I can not get it done since 2 days.

fcgi_stdio.ads

with Interfaces.C;
with Interfaces.C.Strings;

package fcgi_stdio is
    function FCGI_Accept return Interfaces.C.int;
    pragma Import (C, FCGI_Accept, "FCGI_Accept");

    procedure FCGI_printf (str : Interfaces.C.Strings.chars_ptr);
    pragma Import (C, FCGI_printf, "FCGI_printf");
end fcgi_stdio;

test.adb

with fcgi_stdio;
with Interfaces.C;
with Interfaces.C.Strings;

procedure Test is
begin
    while Integer (fcgi_stdio.FCGI_Accept) >= 0 loop
        fcgi_stdio.FCGI_printf (Interfaces.C.Strings.New_String ("Content-Type: text/plain" & ASCII.LF & ASCII.LF));
        fcgi_stdio.FCGI_printf (Interfaces.C.Strings.New_String ("Hello World from Ada!" & ASCII.LF));
    end loop;
end Test;

When I run it in the console, I get following error:

$ ./test
raised STORAGE_ERROR : stack overflow or erroneous memory access

Apache error_log shows:

Premature end of script headers: test

Does anyone have an idea how I can get it working?

È stato utile?

Soluzione

Experimenting on Mac OS X, it seems that the problem is that FCGI_printf() is a varargs function. It calls FCGI_fprintf(), also varargs:

int FCGI_fprintf(FCGI_FILE *fp, const char *format, ...)
{
    va_list ap;
    int n = 0;
    va_start(ap, format);          <------ crash here

Ada doesn't have a standard way of specifying varargs functions, and GNAT doesn't have an implementation-defined way either.

The GNAT documentation says that the solution is to provide a C wrapper for the varargs function:

#include <fcgi_stdio.h>
int FCGI_printf_wrapper(const char *msg)
{
  return FCGI_printf(msg);
}

and import the wrapper:

procedure FCGI_printf (str : Interfaces.C.Strings.chars_ptr);
pragma Import (C, FCGI_printf, "FCGI_printf_wrapper");

Another problem with the program is that in Ada, unlike C and many other languages, "\n" is not a way of inserting a newline character in a string. Try

fcgi_stdio.FCGI_printf
  (Interfaces.C.Strings.New_String ("Content-Type: text/plain" 
                                    & ASCII.LF & ASCII.LF));

[edited 13.1.13]

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top