2012-05-01 17 views
24

Sto cercando di ottenere un set di nove file * .c (e nove file * .h correlati) da compilare in Windows.getopt.h: Compilazione del codice C Linux in Windows

Il codice è stato originariamente progettato in Linux per prendere gli argomenti della riga di comando utilizzando la libreria GNU-Linux/C standard "getopt.h". E quella libreria non si applica alla creazione del codice C in Windows.

Voglio ignorare ciò che fa il mio codice adesso e porre la seguente domanda. Per chi ha familiarità con questa libreria C "getopt.h": sarà possibile creare ed eseguire il mio codice in Windows se dipende dagli argomenti della riga di comando in stile POSIX? O dovrò riscrivere il codice per funzionare per Windows, passando i file di input in modo diverso (e abbandonando la dipendenza "getopt.h")?

+2

se il supporto MSVC non è un requisito difficile, c'è sempre MinGW: I' Sono abbastanza soddisfatto dei pacchetti di cross-compiler MinGW che vengono forniti con Cygwin ... – Christoph

+2

'getopt.h' descrive l'API fornita dai metodi di' getopt.c'. Tiralo da qualche parte, compila e collega il risultato alla tua app e hai fatto. – alk

+1

Solo una volta per quanto riguarda il commento di alk, può essere fatto, tecnicamente, ma la legalità dipende interamente dalla compatibilità delle licenze dalle fonti getopt (se presenti) e da quelle del progetto. Alcune implementazioni getopt dicono che sono di dominio pubblico, quindi probabilmente non ci sarebbero problemi. – user314159

risposta

19

Sei corretto. getopt() è POSIX, non Windows, in genere è necessario riscrivere tutto il codice di analisi dell'argomento della riga di comando.

Fortunatamente, esiste un progetto, Xgetopt, destinato alle classi Windows/MFC.

http://www.codeproject.com/Articles/1940/XGetopt-A-Unix-compatible-getopt-for-MFC-and-Win32

Se si riesce a ottenere questo lavoro nel progetto, che dovrebbe risparmiare un bel po 'di codifica e vi impedisce di dover rielaborare tutta l'analisi.

Inoltre, viene fornito con una bella app demo abilitata per la GUI che dovresti trovare utile.

Buona fortuna!

+0

Lo farò una prova adesso. Ma non posso dire dal link che hai mostrato: l'API di questa libreria è uguale alla vecchia API getopt? – theJollySin

+0

Puoi nominare qualche motivo per fare una riscrittura, ma facendo esercizi di parsing? – alk

+0

Il codice che devi portare è datato quando? @ theJollySin – alk

1

Da quello che mi ricordo di getopt.h, tutto ciò che fa è fornire un parser a portata di mano per l'elaborazione argv dalla tua funzione principale:

int main(int argc, char * argv[]) 
{ 
} 

programmi console di Windows hanno ancora un metodo main, quindi si può semplicemente scorrere il vostro array argv e analizza i parametri da soli. per esempio.

for (int i = 1; i < argc; i++) 
{ 
    if (!strcmp(argv[i], "-f")) 
    filename = argv[++i]; 
} 
+0

Grazie! Non sono sicuro che questo sarà pratico per me. Mentre capisco che potrei scorrere le ~ 5000 linee di codice e riscrivere questi bit, questo è il codice che stiamo ottenendo da altri sviluppatori. Quindi, cosa succede in 2 mesi quando ci danno una versione leggermente più recente del codice? Dovrò ripetere il codice di elaborazione degli argomenti ogni volta che riceviamo un aggiornamento? Sembra una cosa lunga. – theJollySin

+0

Sembra che tu abbia bisogno di stare insieme con questi altri sviluppatori e concordare un argomento che passa il sistema che è portatile. La soluzione fornita da @ theJollySin potrebbe essere la risposta, ma in entrambi i casi non è difficile scrivere un parser di argomento portatile. – Benj

+2

Nel tempo l'API 'getopt' mi è sembrata stabile. @theJollySin – alk

5

ho fatto compilare il codice getopt sotto le finestre.

Ho fatto questo come volevo esplicilty utilizzare la sua funzionalità di analisi della riga di comando in un'applicazione di Windows (riga di comando).

L'ho eseguito correttamente utilizzando VC2010.

Per quanto mi ricordo, non ho riscontrato problemi significativi.

getopt.cgetoptl.c

+2

Una modifica suggerita ha aggiunto la frase * "Si noti che questo codice specifico è coperto dalla GPLv3 e non dalla LGPL." * A questa risposta. L'ho arrotolato indietro e includo il commento qui. –

+0

Er, incluso 'getopt.in.h'? –

+0

@VictorSergienko: è stato necessario un codice di 'getopt.in.h' per compilare le fonti di' getopt'. Ad ogni modo, la mia risposta non voleva essere compresa nel modo in cui la compilazione dei file collegati era possibile senza alcune (minori) modifiche. Nutrirli "così come sono" con VC10 non funzionerebbe. – alk

3

C'è una possibilty di utilizzare il codice da MinGW runtime (da Todd C. Miller):

http://sourceforge.net/apps/trac/mingw-w64/browser/trunk/mingw-w64-crt/misc

Ho creato una piccola biblioteca con questi file e lo script CMake (in grado di generare un progetto VS):

https://github.com/alex85k/wingetopt

+0

Sembra che la tua libreria sarebbe stata molto utile. Volevo solo dire. Ma ho visto il commento di Dogbert su Xgetopt e questo ha fatto il trucco. Grazie comunque! – theJollySin

32

getopt() è in realtà una funzione davvero semplice.Ho fatto un github gist per esso, il codice from here è al di sotto troppo

#include <string.h> 
#include <stdio.h> 

int  opterr = 1,    /* if error message should be printed */ 
    optind = 1,    /* index into parent argv vector */ 
    optopt,     /* character checked for validity */ 
    optreset;    /* reset getopt */ 
char *optarg;    /* argument associated with option */ 

#define BADCH (int)'?' 
#define BADARG (int)':' 
#define EMSG "" 

/* 
* getopt -- 
*  Parse argc/argv argument vector. 
*/ 
int 
    getopt(int nargc, char * const nargv[], const char *ostr) 
{ 
    static char *place = EMSG;    /* option letter processing */ 
    const char *oli;      /* option letter list index */ 

    if (optreset || !*place) {    /* update scanning pointer */ 
    optreset = 0; 
    if (optind >= nargc || *(place = nargv[optind]) != '-') { 
     place = EMSG; 
     return (-1); 
    } 
    if (place[1] && *++place == '-') {  /* found "--" */ 
     ++optind; 
     place = EMSG; 
     return (-1); 
    } 
    }          /* option letter okay? */ 
    if ((optopt = (int)*place++) == (int)':' || 
    !(oli = strchr(ostr, optopt))) { 
     /* 
     * if the user didn't specify '-' as an option, 
     * assume it means -1. 
     */ 
     if (optopt == (int)'-') 
     return (-1); 
     if (!*place) 
     ++optind; 
     if (opterr && *ostr != ':') 
     (void)printf("illegal option -- %c\n", optopt); 
     return (BADCH); 
    } 
    if (*++oli != ':') {     /* don't need argument */ 
    optarg = NULL; 
    if (!*place) 
     ++optind; 
    } 
    else {         /* need an argument */ 
    if (*place)      /* no white space */ 
     optarg = place; 
    else if (nargc <= ++optind) { /* no arg */ 
     place = EMSG; 
     if (*ostr == ':') 
     return (BADARG); 
     if (opterr) 
     (void)printf("option requires an argument -- %c\n", optopt); 
     return (BADCH); 
    } 
    else       /* white space */ 
     optarg = nargv[optind]; 
    place = EMSG; 
    ++optind; 
    } 
    return (optopt);      /* dump back option letter */ 
} 
+2

Ho incluso questo nel mio progetto, tuttavia quando provo a usare optarg si dice che non è dichiarato in Windows. Il valore di ritorno di getopt è sempre l'opt. Come posso usare optarg? – eleijonmarck

+2

Nel file di intestazione mancano 'extern char * optarg;' e 'extern int optind, opterr, optopt;' – cubrr

1

si potrebbe provare a guardare in glib-2.0 come alternativa. Sarebbe un po 'grande per il solo bisogno di un parser di opzioni. Il lato positivo avrebbe accesso a tutti gli altri meravigliosi giocattoli nella lob.

Giusto per essere onesto, non ho provato a farlo funzionare (io rimango principalmente su Linux), quindi YMMV.

Ottenere glib per funzionare in Windows: HowTo

Oh, si potrebbe esplorare usando MinGW per l'ambiente di sviluppo, e Visual Studio per il vostro IDE.

Glib per Win32: HowTo

Anywho, spero che questo aiuta.

1

se si vuole solo che venga utilizzato in visual C++ senza altre dipendenze, ho portato il getopt.c dall'ultima versione di libra 2.12, con tutte le nuove funzionalità. L'unica differenza è che devi usare TCHAR invece di char, ma questo è molto comune in Windows.

scaricare semplicemente l'origine, creare, copiare libgetopt.lib e getopt.h getopt_int.h nel progetto.

puoi anche farlo utilizzando CMakeList.txt nella directory principale.

download the source from github

0

Il getopt.h esiste in git, ho scaricarlo e funziona per me:

https://gist.github.com/ashelly/7776712

+0

Beh, trovare getopt.h non era un mio problema. Ero più preoccupato per il fatto che Windows getopt.h funzionasse in un ambiente Linux. Buono a sapersi però. – theJollySin

Problemi correlati