2013-01-12 1 views
4

J'ai trouvé http://support.zeus.com/zws/examples/2005/12/16/hello_world_in_perl_and_c et ces deux exemples fonctionnent.FastCGI avec Ada

Maintenant, j'ai essayé cela pour Ada et je ne peux pas le faire depuis 2 jours.

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; 

Quand je lance dans la console, je suis après erreur:

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

Apache error_log Expositions:

Premature end of script headers: test 

Quelqu'un at-il une idée de comment je peux le faire fonctionner?

Répondre

7

En expérimentant sur Mac OS X, il semble que le problème est que FCGI_printf() est une fonction varargs. Il appelle FCGI_fprintf(), aussi varargs:

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

Ada n'a pas un moyen standard de spécifier les fonctions varargs et GNAT ne dispose pas d'une mise en œuvre définie manière non plus.

Le GNAT documentation dit que la solution est de fournir une enveloppe C pour la fonction varargs:

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

et importer l'emballage:

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

Un autre problème avec le programme est qu'en Ada, Contrairement à C et à beaucoup d'autres langages, "\n" n'est pas un moyen d'insérer un caractère de nouvelle ligne dans une chaîne. Essayez

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

[édité 13.1.13]

+0

Merci, je l'ai corrigé! Mais les erreurs sont toujours les mêmes. – user1091344

+0

Merveilleux, mon héros :-) Ça marche. – user1091344

+0

Puis-je demander, comment programmez-vous sur votre Mac? Comment avez-vous obtenu l'information sur la ligne va_start (ap, format)? – user1091344