我有一个C项目,旨在可移植到各种(PC和嵌入式)平台.
应用程序代码将使用具有特定于平台的实现的各种调用,但共享一个通用(通用)API以帮助实现可移植性.我试图找到最合适的方式来声明函数原型和结构.
这是我到目前为止所提出的:
main.c中:
#include "generic.h"
int main (int argc, char *argv[]) {
int ret;
gen_t *data;
ret = foo(data);
...
}
Run Code Online (Sandbox Code Playgroud)
generic.h :(平台无关包括)
typedef struct impl_t gen_t;
int foo (gen_t *data);
Run Code Online (Sandbox Code Playgroud)
impl.h :(特定于平台的声明)
#include "generic.h"
typedef struct impl_t {
/* ... */
} gen_t;
Run Code Online (Sandbox Code Playgroud)
impl.c :(特定于平台的实现)
int foo (gen_t *data) {
...
}
Run Code Online (Sandbox Code Playgroud)
建立:
gcc -c -fPIC -o platform.o impl.c
gcc -o app main.c platform.o
Run Code Online (Sandbox Code Playgroud)
现在,这似乎有效......因为它编译好了.但是,我通常不会标记我的结构,因为它们永远不会在typedef"别名" 之外访问.这是一个小挑选,但我想知道是否有办法与匿名结构达到相同的效果?
我也要求后代,因为我搜索了一段时间,我找到的最接近的答案是:( 链接)
在我的情况下,这不是正确的方法,因为应用程序特别不应该直接包含实现头 - 整个点是将程序与平台分离.
我看到了其他一些不太理想的方法来解决这个问题,例如: …
首先,我是socket编程的新手,所以我可能会遗漏一些明显的东西.
目标:
我正在尝试编写一个小工具来手工制作ARP帧并将其发送到线路上,然后收听回复.我正在使用AF_PACKET,SOCK_DGRAM,因此内核处理以太网头/尾部,但我在发送和接收时获得对帧的数据部分的原始访问.
该应用程序本质上是诊断性的,因此现有API和用户态工具不适用.我试图在广播域中找到响应ARP请求的一个(或多个)设备,但我并不关心填充系统ARP缓存或类似的东西.
题:
我希望用户能够按名称指定接口,或者使用适当的默认值.到目前为止,如果我指定接口,一切都很完美...但如果我不这样做,我不确定如何最好地处理bind()和sendto().
细节:
以下是相关代码的代表性示例.假设*cfg指向预先分配的结构,使用cfg-> interface.name =="eth0":
int i;
int sock;
void *buf;
struct my_config_options *cfg;
struct ifreq ifr;
struct sockaddr_ll addr;
struct pollfd pfd;
// Packet buffer
buf = malloc(BUF_LEN);
if (buf == NULL) {
return 0;
}
// Open a socket
sock = socket(AF_PACKET, SOCK_DGRAM, 0);
if (sock_fd == -1) {
return 0;
}
// Get interface index
strncpy(ifr.ifr_name, cfg->interface.name, IFNAMSIZ);
if (ioctl(sock, SIOCGIFINDEX, &ifr) == -1) {
return 0;
}
cfg->interface.idx = ifr.ifr_ifindex;
// …Run Code Online (Sandbox Code Playgroud)