getopt.h: compilación de código C de Linux en Windows

7 minutos de lectura

avatar de usuario
juan_ciencia

Estoy tratando de obtener un conjunto de nueve archivos *.c (y nueve archivos *.h relacionados) para compilar en Windows.

El código se diseñó originalmente en Linux para tomar argumentos de la línea de comandos utilizando la biblioteca estándar GNU-Linux/C “getopt.h”. Y esa biblioteca no se aplica a la creación del código C en Windows.

Quiero ignorar lo que hace mi código en este momento y hacer la siguiente pregunta. Para aquellos de ustedes que están familiarizados con esta biblioteca C “getopt.h”: ¿será posible compilar y ejecutar mi código en Windows si depende de argumentos de línea de comandos de estilo POSIX? ¿O tendré que volver a escribir el código para que funcione para Windows, pasando los archivos de entrada de manera diferente (y eliminando la dependencia “getopt.h”)?

  • si el soporte de MSVC no es un requisito difícil, siempre está MinGW: estoy muy contento con los paquetes de compilación cruzada de MinGW que vienen con Cygwin…

    – Cristóbal

    1 de mayo de 2012 a las 21:28

  • getopt.h describe la API proporcionada por los métodos de getopt.c. Sáquelo de algún lugar, compílelo y vincule el resultado a su aplicación y listo.

    – alk

    1 mayo 2012 a las 21:40


  • Solo un comentario con respecto al comentario de alk, se puede hacer, técnicamente, pero la legalidad depende completamente de la compatibilidad de la (s) licencia (s) de las fuentes de getopt (si las hay) y las del proyecto. Algunas implementaciones de getopt dicen dominio público, por lo que probablemente no sea un problema.

    usuario2895783

    18 de marzo de 2017 a las 15:56

avatar de usuario
bobobobo

getopt() es en realidad una función muy simple. Hice una esencia de github para ello, código de aquí esta abajo tambien

#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 */
}

  • Tengo esto incluido en mi proyecto, sin embargo, cuando trato de usar optarg, dice que no está declarado en Windows. El valor de retorno de getopt es siempre opt. ¿Cómo puedo usar optarg?

    – eleijónmarck

    30 de enero de 2015 a las 9:42

  • Falta el archivo de cabecera extern char *optarg; y extern int optind, opterr, optopt;

    – cbr

    17 de enero de 2017 a las 17:18

avatar de usuario
Nube

Estás en lo correcto. getopt() es POSIX, no Windows, generalmente tendría que volver a escribir todo el código de análisis de argumentos de la línea de comandos.

Afortunadamente, hay un proyecto, Xgetopt, que está destinado a las clases de Windows/MFC.

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

Si puede hacer que esto funcione en su proyecto, debería ahorrarle un poco de codificación y evitar que tenga que volver a trabajar en todo el análisis.

Además, viene con una buena aplicación de demostración habilitada para GUI que debería resultarle útil.

¡Buena suerte!

  • Lo intentaré ahora mismo. Pero no puedo decirlo por el enlace que mostró: ¿la API para esta biblioteca es la misma que la antigua API getopt?

    – john_ciencia

    1 de mayo de 2012 a las 21:28

  • ¿Podría nombrar alguna razón para hacer una reescritura, pero haciendo ejercicios de análisis?

    – alk

    1 de mayo de 2012 a las 21:44

  • Bueno, el código que estoy transfiriendo (para usar en un sistema mucho más grande) tiene unos meses. Pero las personas que lo desarrollan son tanto científicos como ingenieros, por lo que generalmente no usan los compiladores más nuevos o incluso las versiones más nuevas de UNIX/LINUX. Entonces, si están haciendo las cosas a la antigua, no me sorprendería.

    – john_ciencia

    1 de mayo de 2012 a las 21:58

  • ‘algunos meses’ 🙂 no hay problemas con getopt siendo demasiado joven o incluso maduro… es muy posible que le des una oportunidad y tire del getopt fuentes de los enlaces en mi respuesta y utilícelos.

    – alk

    1 de mayo de 2012 a las 22:02


  • @Dogbert Esa fue casi la solución perfecta. Excepto que estoy teniendo un momento realmente molesto al intentar ejecutar la biblioteca que vinculó (que es C ++) con el código base que tengo actualmente (que es C). Todavía no he renunciado a que esto sea posible, pero mezclar los dos tipos de lenguaje parece agregar cierta complejidad a las compilaciones de Visual Studio.

    – john_ciencia

    2 mayo 2012 a las 19:52

Existe la posibilidad de usar el código del tiempo de ejecución de MinGW (por Todd C. Miller):

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

Creé una pequeña biblioteca con estos archivos y el script CMake (puede generar un proyecto VS):

https://github.com/alex85k/wingetopt

  • Parece que su biblioteca habría sido muy útil. Solo quería decir. Pero primero vi el comentario de Dogbert sobre Xgetopt y funcionó. ¡Gracias, sin embargo!

    – john_ciencia

    13 de septiembre de 2013 a las 15:58

  • Gracias. Eso funciona copiar y pegar para un puerto rápido para usar un programa realmente rápido

    – nombre cero

    29 de junio de 2020 a las 15:16


avatar de usuario
alca

I hizo compilar el getopt código bajo las ventanas.

Hice esto como quería explicidad use su funcionalidad de análisis de línea de comando en una aplicación de Windows (línea de comando).

Hice esto con éxito usando VC2010.

Por lo que recuerdo, no encontré problemas significativos al hacerlo.

getopt.c getoptl.c

avatar de usuario
arquero han

si solo quiere que getopt se use en visual c++ sin otras dependencias, tengo el puerto getopt.c de la última gnu libc 2.12, con todas las características nuevas. La única diferencia es que tiene que usar TCHAR en lugar de char, pero esto es muy común en las ventanas.

simplemente descargue la fuente, cree, copie libgetopt.lib y getopt.h getopt_int.h en su proyecto.

también puede hacerlo usando CMakeList.txt en el directorio raíz.

descargar la fuente de github

avatar de usuario
rnordeen

Puede intentar buscar en glib-2.0 como alternativa. Sería un poco grande para solo necesitar un analizador de opciones. El lado positivo sería tener acceso a todos los otros juguetes maravillosos del simplismo.

Solo para ser honesto, no he intentado hacer que esto funcione (me limito principalmente a Linux), así que YMMV.

Hacer que Glib funcione en Windows: Cómo

Oh, puede explorar el uso de mingw para el entorno de compilación y Visual Studio para su IDE.

Glib para Win32: Cómo

De todos modos, espero que esto ayude.

avatar de usuario
Steven Fosdick

Según mi lectura de la documentación, el archivo de encabezado getopt.h es específico de la biblioteca GNU C tal como se usa con Linux (y Hurd). La función getopt en sí ha sido estandarizada por POSIX, que dice que debe declararse, junto con optind optarg, etc. en unistd.h

No puedo probar esto en Visual Studio, pero valdría la pena verificar si unistd.h existe y declara esta función, ya que Visual Studio proporciona algunas otras funciones POSIX.

De lo contrario, definitivamente tomaría una implementación de getopt en lugar de volver a escribir el análisis del argumento para que funcione sin él. Getopt fue escrito para hacer las cosas más fáciles para el programador y más consistentes para el usuario de programas con argumentos de línea de comandos. Sin embargo, verifique la licencia.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad