IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

structure logiciel - interface et wrapper


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Par défaut structure logiciel - interface et wrapper
    bonjour, dans le cadre d'un projet, je dois développer un protocole de transfert spécifique au besoin de mon client. Mon chef m'a expliqué en deux mots ce que je devais faire au niveau de la structure du logiciel.

    en effet, je dois utiliser le protocole de transport UDP pour le transfert des données mais il faut aussi prévoir qu'un jour on puisse utiliser un autre protocole de couche 4 comme TCP par exemple. De plus, on doit assurer le fonctionnement avec windows et / ou linux.

    Il m'a dit de faire un header (une interface) if_net.h qui contient la liste des services nécessaire (select_socket, send, receive, close, create etc.) puis de faire des wrappers (fichier .c) qui incluent mon interface .h.

    Pouvez-vous me dire s'il existe des règles de structures ou des examples pour bien réaliser ce type d'oppération ? Voici ce que j'ai fais pour le moment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #ifndef _IF_NET_H
    #define _IF_NET_H
     
    //include system header
    #include <stdio.h>
    #include <stdin.h>
     
    /* if_net.h is the interface between the reader process and the printhead */
     
    int if_net_open_socket();
    int if_net_select_socket();
    int if_net_send();
    int if_net_receive();
    int if_net_close_socket();
     
    #endif
    puis j'aimerai créer par la suite 2 fichiers .c du style if_net_udp_linux.c et if_net_udp_win.c par exemple qui incluent mon if_net.h

    merci et votre aide

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 56
    Par défaut
    bonjour,

    La structure, c'est celle que tu définis dans ton .h, comme une interface en java par exemple.
    La seule subtilité, c'est au moment de la compilation, soit tu compiles le fichier
    if_net_udp_unix.c, soit if_net_tcp_windows.c par exemple.
    et tous ces fichiers .c doivent implanter les fonctions du .h (sinon, ça ne compile pas de toute façon). Cela va générer des .o différents et le linker n'y verra que du feux (il faut lui préciser le seul et unique .o que tu veux linker).
    Pour rappel créer un exécutable à partir des sources c'est :
    1) compiler chaque .c pour en faire un .o
    2)linker (lier) ces .o pour en faire un exécutable
    en simplifié, il y a aussi la précompilation...

    Si tu ne peux pas gérer ceci à la compilation (par exemple si tu dois définir le protocole utilisé en ligne de commande à l’exécution), il faut utiliser dlopen.
    Le principe est de charger dynamiquement les fonctions, avec quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    void* lib;//la librairie à charger
     
    typedef int if_net_open_socket();//typedef sur une fonction simplifie la notation
    bool loadIfNetFunctions(char* path)//charger toutes les fonctions, à ne faire qu'une fois
    //path est le chemin d'un fichier .so compilé avec :
    //gcc -shared -o if_net.so if_net_udp_socket.o other_functions.o
    {
       //load library
       lib = dlopen(path, RTLD_LAZY);
       if (!lib) {
          //erreur
          return false;
       }
     
       // reset errors
       dlerror();
     
       // open
       const char* dlsym_error;
       //on charge une fonction
       if_net_open_socket* open_socket = (if_net_open_socket*) dlsym(lib, "if_net_open_socket");
       dlsym_error = dlerror();
       if (dlsym_error) {
          printf("Cannot load symbol open: %s", dlsym_error);
          return false;
       }
       //la même chose pour toutes les autres fonctions
    }
     
    void closeIfNetFunctions()
    {
          dlclose(lib);
    }
     
    //quelque part dans le programme :
    int ret = open_socket(); //open_socket est l'adresse de la fonction if_net_open_socket
    Ceci est valable pour les unix-like. Pour windows, le fonctionnement est similaire mais les noms sont différents : wikipedia fait le parallèle ici.
    Je ne suis pas sûr à 100% du code car je le fait en c++ et que je n'ai pas encore testé (par exemple open_socket doit être visible dans le programme).
    En espérant que tu puisses te contenter du linkage statique (à la compilation et non à l'exécution), bon courage.

  3. #3
    Membre éprouvé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Par défaut
    Salut et merci pour ta réponse. Ceci me semble très compliqué. Je ne sais pas si je me suis bien exprimé. Je voyais plus un truc comme ça par exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    #ifndef _IF_NET_H
    #define _IF_NET_H
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
     
    #if defined (WIN32)
    	#include "winsock2.h"
    	typedef int socklen_t;
    #elif defined (linux)
    	#include <sys/types.h>
    	#include <sys/socket.h>
    	#include <netinet/in.h>
    	#include <arpa/inet.h>
    	#include <unistd.h>
     
    	typedef int SOCKET;
    	typedef struct sockaddr_in SOCKADDR_IN;
    	typedef struct sockaddr SOCKADDR;
    #endif
     
     
    /*
     * Create and configure a new socket with the following parameters
     * @param domain 	: AF_INET for an IPv4 communication, AF_UNIX for an interprocess communication
     * @param type   	: SOCK_DGRAM for UDP, SOCK_STREAM for TCP
     * @param port		: Listen port. Must be > 1024 and < 65535
     * @return			: The return value is the socket identifier
     * */
    SOCKET if_net_open_socket(int domain, int type, int port);
    int if_net_select_socket();
    int if_net_send();
    int if_net_receive();
    int if_net_close_socket();
     
    #endif
    et ensuite dans les .c, je développe les fonctions correspondantes.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 56
    Par défaut
    Salut,

    Oui, c'est aussi une possibilité et dans le .c, tu ferais aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #ifdef WIN32
    //toutes les fonctions pour windows
    #else
    //les même fonctions pour linux
    #endif
    L'avantage avec cette méthode est qu'il n'y a rien à faire pour le linkage de particulier.
    L'avantage avec l'autre (linkage statique, tu n'as pas l'air d'avoir besoin du linkage dynamique), c'est que c'est dans les .c que tu fais ta tambouille et ça ne regarde personne d'autre que celui qui les fait (donc toi). C'est un peu de l'encapsulation. Et si un jour, tu décides d'utiliser autre chose que des sockets, tu fais de nouveaux .c et il n'y a rien à toucher au .h. Ceux qui utilisent ton interface (le .h), sont sûrs de ne pas avoir à modifier leur code. C'est vrai que dans ton cas, cet avantage n'est peut-être pas énorme comparé au temps que ça peut prendre pour configurer le Makefile. De plus, il faudrait définir SOCKET dans les .c et faire un typedef sur ce SOCKET dans le .h avec un autre nom, exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    //if_net_udp_linux.c
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
     
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;//l'interface n'a pas besoin de connaître SOCKADDR_IN
    typedef struct sockaddr SOCKADDR;
     
    socket if_net_open_socket(int domain, int type, int port){...}
    int if_net_select_socket(){...}
    int if_net_send(){...}
    int if_net_receive(){...}
    int if_net_close_socket(){...}
     
    //if_net_udp_windows.c
    #include "winsock2.h"
    typedef int socklen_t;
     
    socket if_net_open_socket(int domain, int type, int port){...}
    int if_net_select_socket(){...}
    int if_net_send(){...}
    int if_net_receive(){...}
    int if_net_close_socket(){...}
     
    //if_net.h
    typedef SOCKET socket;
    socket if_net_open_socket(int domain, int type, int port);
    int if_net_select_socket();
    int if_net_send();
    int if_net_receive();
    int if_net_close_socket();
    C'est censé être plus propre mais bon, ta méthode est tout à fait valable et surtout plus rapide à coder.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Par défaut
    Oui mon idée c'est de créer un ensemble de fonctions utilisable sur les deux OS par exemple. J'aurai même 2 fichiers .C avec mes fonctions puis dans le main je refais le test si c'est un windows ou un linux pour les petites variantes à ajouter comme par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #if defined (WIN32)
            WSADATA WSAData;
            int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
        #else
            int erreur = 0;
        #endif
    mais après l'appel des fonction reste identique

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 56
    Par défaut
    Je ne sais pas trop où tu veux mettre tes tests (ifdef WIN32...) mais il est tout de même plus commode de ne les faire que dans ce qui touche à if_net et pas dans le main. Donc si tu prends l'architecture que tu as fait dans le post #3, c'est bon, et les erreurs "bas niveau" liées aux sockets ne doivent être traitée que dans les if_net_*.c. C'est peut-être ce que tu voulais faire mais c'est vraiment plus commode de bien séparer ce qui doit être caché au main du main.

Discussions similaires

  1. Logiciel interface graphique JSF/PrimeFaces
    Par velocity dans le forum JSF
    Réponses: 4
    Dernier message: 07/06/2013, 16h50
  2. Réponses: 10
    Dernier message: 11/06/2012, 00h22
  3. logiciel interface homme automate
    Par tomi1205 dans le forum Automation
    Réponses: 3
    Dernier message: 20/05/2012, 18h22
  4. Logiciel à Interface Windows : Quelle langage de programmation ?
    Par woresa dans le forum Langages de programmation
    Réponses: 8
    Dernier message: 23/03/2012, 17h51
  5. [Logiciel]Cherche graphisme pour des interfaces visuelles
    Par smyley dans le forum Autres Logiciels
    Réponses: 9
    Dernier message: 14/11/2004, 02h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo