Допустим, у меня есть общий интерфейс определения в comm.h
, который выглядит следующим образом:
/*comm.h*/
typedef struct comm{
char *ip_addr;
unsigned int port;
}comm_t;
struct comm_node{
uint8_t comm_node_number;
char topic_name[5];
struct comm_operations *comm_ops;
};
struct comm_operations{
int (*comm_init) (struct comm_node *comm_node,struct comm *comm_p);
int (*comm_release)(struct comm_node *comm_node);
/*abstrct the commnucation technologies*/
ssize_t (*comm_recvfrom)(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t (*comm_sendto)(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
};
Из приведенного выше кода легко увидеть, что это общий интерфейс объекта связи для различных протоколов, таких как Сокет TCP / UDP.
Но я хочу сделать каждый коммуникационный сокет comm_node
в моей структуре, но оставлю их детальную реализацию struct comm_operations
unknown
(Более конкретно, скажем, у меня есть еще два файла udp_comm_impl.h
/ udp_comm_impl.c
и tcp_comm_impl.h
/ tcp_comm_impl.c
, и все они включают comm.h
и реализуют функцию обратного вызова, определенную в struct comm_operations
в своем собственном коде)
Моя цель - иметь структуру данных для хранения всех comm_node
в другом c -файле (скажем, main.c
), поэтому у меня будет несколько протоколов сокетов, которые все они реализуют comm_operations
, и мне не нужно заботиться о подробно, просто вызывайте соответствующую операцию каждого comm_node, когда это необходимо.
Вот вопрос, который смутил меня: как main.c
регистрирует эти comm_node
объекты, пока не знает их существования b раньше? (Как и при написании linux модуля ядра, ядро не знало, что реализация драйвера устройства будет существовать, но оно может динамически проверять модуль.) Возможно ли это в пространстве пользователя? И если это возможно, что я должен сделать, чтобы мой main.c
быть в состоянии динамически исследовать их?