2008-08-13 12 views
8

Tengo este programa, lo llamaremos Host. El anfitrión hace todo tipo de cosas buenas, pero necesita poder aceptar entradas a través de la línea de comandos mientras se ejecuta. Esto significa que de alguna manera debe enviar sus otros datos de proceso y luego abandonarlo. Por ejemplo, tengo que ser capaz de hacer esto:Enviar mensajes al programa a través de la línea de comando

./Host --blahblah 3 6 3 5 

Esto debe de alguna manera acabar llamando a alguna función en Host llama

handleBlahBlah(int x1, int y1, int x2, int y2){ 
    //do some more sweet stuff 
} 

anfitrión es un programa C, y no es necesario para soportar múltiples instancias.

Un ejemplo de esto es el reproductor de música Amarok. Con Amarok corriendo y jugando, puede escribir "amarok --pause" y pausará la música.

Necesito poder hacer esto en Linux o Windows. Preferiblemente Linux.

¿Cuál es la forma más limpia de implementar esto?

+0

¿Quieres pasarle argumentos cuando el programa ya se está ejecutando? ¿Para qué sistema operativo se está programando esto? –

Respuesta

-2

Entonces, me puede estar faltando el punto aquí, pero por deafult una función principal del programa C toma dos argumentos; argc, un recuento del número de argumentos (al menos uno) y argv (o vector arg), la lista de argumentos. Podría analizar los argumentos y llamar al método correcto. Por ejemplo:

int main(int argc, *argv[]) 
{ 
    /*loop through each argument and take action*/ 
     while (--argc > 0) 
     { 
      printf(%s%s, *++argv, (argc > 1) ? " " : ""); 
     } 
} 

imprimiría todos los argumentos de la pantalla. No soy un gurú C, así que espero no haber cometido ningún error.

EDITAR: Ok, estaba buscando algo más, pero no estaba muy claro antes de que se editara la pregunta. No tiene que saltar en mi representante ...

8

Si estuviera en Windows, le diría que use una ventana oculta para recibir los mensajes, pero ya que usó ./, supongo que quiere algo Unix- basado.

En ese caso, yo iría con un named pipe. Sun tiene un tutorial sobre tuberías con nombre que pueden ser útiles.

El programa probablemente crearía la tubería y escucharía. Podría tener un script de línea de comandos separado que abriría el conducto y solo le haría eco de sus argumentos de línea de comando.

podría modificar su programa para admitir el envío de línea de comandos en lugar de utilizar un script separado. Harías lo mismo básico en ese caso. Su programa vería los argumentos de la línea de comandos y, si corresponde, abrirá el conducto a la instancia "principal" del programa y enviará los argumentos.

+1

+1 He usado esta metodología de tuberías con nombre varias veces y funciona bastante bien. También utilicé conectores UNIX para casos en los que el programa principal necesitaba devolver datos al script/programa de la línea de comandos. – jschmier

5

Si necesita ser multiplataforma, puede considerar hacer que la instancia en ejecución escuche en un puerto TCP y hacer que la instancia que inicie desde la línea de comando envíe un mensaje a ese puerto.

4

Sugiero usar ya sea un Unix socket o D-Bus. Usar un socket podría ser más rápido si está familiarizado con la programación de sockets de Unix y solo quiere algunas operaciones, mientras que D-Bus podría hacer que sea más fácil concentrarse en la implementación de la funcionalidad de una manera familiar orientada a objetos.

Eche un vistazo a Beej's Guide to Unix IPC, particularmente el capítulo en Unix sockets.

1

Lo que nadie ha dicho aquí es esto: "no se puede llegar desde aquí".

La línea de comandos solo está disponible tal como estaba cuando se invocó el programa.

El ejemplo de invocar "fillinthename argumentos ..." para comunicarse con fillinthename una vez fillinthename se ejecuta sólo puede lograrse mediante el uso de dos instancias del programa que se comunican entre sí.

Las otras respuestas sugieren formas de lograr la comunicación.

Un amarok como programa necesita para detectar la existencia de otra instancia de sí mismo con el fin de saber qué papel que debe desempeñar el papel principal de receptor del mensaje/servidor persistente, o el papel secundario de un solo disparo remitente del mensaje

editado para que se muestre realmente la palabra fillinthename.

0

Una técnica que he visto es hacer que su programa Host sea simplemente un "caparazón" para su programa real. Por ejemplo, cuando inicia su aplicación normalmente (por ejemplo, ./Host), el programa se integrará en la parte de la "aplicación principal" de su código. Cuando inicie su programa de una manera que sugiera que desea señalizar la instancia en ejecución (por ejemplo, ./Host --send-message restart), el programa se insertará en la parte del "remitente del mensaje" de su código. Es como tener dos aplicaciones en una. Otra opción que no utiliza fork es hacer Host puramente una aplicación de "mensaje remitente" y tener su "aplicación principal" como un ejecutable por separado (por ejemplo: Host_core) que Host se puede iniciar por separado.

La parte de la "aplicación principal" de su programa deberá abrir algún tipo de canal de comunicación para recibir mensajes, y la parte del "remitente del mensaje" deberá conectarse a ese canal y usarlo para enviar mensajes. Hay varias opciones diferentes disponibles para enviar mensajes entre procesos. Algunos de los métodos más comunes son pipes y sockets. Dependiendo de su sistema operativo, puede tener opciones adicionales disponibles; por ejemplo, QNX tiene channels y BeOS/Haiku tiene BMessages. También puede encontrar una biblioteca que recomponga esta funcionalidad, como lcm.

Cuestiones relacionadas