#define PRODUCT_LEN sizeof(struct Product) 有什么用
时间: 2024-02-17 19:03:40 浏览: 82
这个宏定义 PRODUCT_LEN 用于获取结构体 Product 的大小,以便在进行内存分配、拷贝等操作时使用。具体来说,这个宏定义展开后会被替换成 sizeof(struct Product) 这个表达式,即结构体 Product 的大小。使用这个宏定义可以保证在不同的平台上,对结构体的大小的获取都是正确的,从而避免了因为不同的编译器、操作系统等因素导致的结构体大小不一致的问题。
例如,在进行内存分配时,可以这样使用宏定义:
```c
struct Product *pPro = (struct Product *)malloc(PRODUCT_LEN);
```
相当于展开成:
```c
struct Product *pPro = (struct Product *)malloc(sizeof(struct Product));
```
这样就可以保证分配的内存大小与结构体大小一致,避免了因为手动计算结构体大小而导致的错误。
相关问题
使用inotify获取usb设备插拔事件,并提取出设备类型,名字,pid vid 文件路径等信息,不使用libudev,请用C语言写出程序
好的,以下是使用inotify获取usb设备插拔事件并提取设备信息的C语言程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <string.h>
#define EVENT_SIZE (sizeof(struct inotify_event))
#define BUF_LEN (1024 * (EVENT_SIZE + 16))
int main(void)
{
int fd, wd;
char buf[BUF_LEN];
int len, i = 0;
struct inotify_event *event;
fd = inotify_init();
if (fd < 0) {
perror("inotify_init");
return EXIT_FAILURE;
}
wd = inotify_add_watch(fd, "/dev/", IN_CREATE | IN_DELETE);
if (wd < 0) {
perror("inotify_add_watch");
return EXIT_FAILURE;
}
while (1) {
len = read(fd, buf, BUF_LEN);
if (len < 0) {
perror("read");
return EXIT_FAILURE;
}
i = 0;
while (i < len) {
event = (struct inotify_event *)&buf[i];
if (event->mask & (IN_CREATE | IN_DELETE)) {
if (strstr(event->name, "usb")) {
char sys_path[256];
char vid[5], pid[5];
char *devname;
FILE *fp;
sprintf(sys_path, "/sys/class/%s/%s/device/uevent", event->name, event->name);
fp = fopen(sys_path, "r");
if (fp == NULL) {
perror("fopen");
return EXIT_FAILURE;
}
while (fgets(buf, sizeof(buf), fp)) {
if (strstr(buf, "PRODUCT=")) {
sscanf(buf, "PRODUCT=%4s/%4s/", vid, pid);
} else if (strstr(buf, "DEVNAME=")) {
buf[strlen(buf) - 1] = '\0';
devname = strrchr(buf, '/');
printf("Device %s %s (VID=%s PID=%s)\n", event->mask & IN_CREATE ? "added" : "removed", devname + 1, vid, pid);
}
}
fclose(fp);
}
}
i += EVENT_SIZE + event->len;
}
}
inotify_rm_watch(fd, wd);
close(fd);
return EXIT_SUCCESS;
}
```
程序中使用inotify监听/dev/目录下的IN_CREATE和IN_DELETE事件,并检查设备名是否带有“usb”字符串。如果是,则根据/sys/class/目录下的相应设备目录中的uevent文件提取出设备的VID、PID、设备名等信息并打印出来。
请使用netlink获取usb设备插拔事件,并提取出设备类型,名字,pid vid 文件路径等信息,使用inotify 监听,请用C语言写出程序
好的,我会尽力回答您的问题。首先,您需要了解一些基本概念和工具,例如Linux的netlink和inotify机制,以及C语言的基本语法。
Netlink是Linux内核中用于内核和用户空间进程之间通信的一种机制。可以使用Netlink来获取有关网络、路由、设备和进程等信息。通过Netlink,我们可以监听USB设备插拔事件并提取设备信息。
Inotify是Linux内核用于监视文件系统事件的一种机制。可以使用inotify API来监听文件系统中的特定文件或目录的事件。通过inotify,我们可以监听USB设备的挂载和卸载事件,并获取文件路径信息。
下面是一个简单的C语言程序,演示如何使用Netlink和inotify来获取USB设备插拔事件,并提取设备类型、名字、PID、VID和文件路径等信息。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <sys/inotify.h>
#define UEVENT_BUFFER_SIZE 2048
#define MAX_NAME_SIZE 256
int main(int argc, char* argv[]) {
int sockfd, inotify_fd, watch_fd;
char buf[UEVENT_BUFFER_SIZE];
char name[MAX_NAME_SIZE];
struct sockaddr_nl sa;
struct inotify_event event;
socklen_t len = sizeof(sa);
ssize_t n;
// create netlink socket
sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
if (sockfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;
sa.nl_groups = NETLINK_KOBJECT_UEVENT;
// bind netlink socket
if (bind(sockfd, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
perror("bind");
close(sockfd);
exit(EXIT_FAILURE);
}
// initialize inotify
inotify_fd = inotify_init();
if (inotify_fd == -1) {
perror("inotify_init");
close(sockfd);
exit(EXIT_FAILURE);
}
// add watch for mountpoint
watch_fd = inotify_add_watch(inotify_fd, "/dev", IN_CREATE | IN_DELETE);
if (watch_fd == -1) {
perror("inotify_add_watch");
close(inotify_fd);
close(sockfd);
exit(EXIT_FAILURE);
}
while (1) {
// receive netlink message
n = recv(sockfd, buf, sizeof(buf), 0);
if (n == -1) {
perror("recv");
continue;
}
// parse netlink message
for (char* ptr = buf; ptr < buf + n;) {
struct nlmsghdr* nh = (struct nlmsghdr*)ptr;
if (nh->nlmsg_type == NLMSG_DONE) {
break;
}
if (nh->nlmsg_type == NLMSG_ERROR) {
perror("netlink error");
break;
}
if (nh->nlmsg_type == UDEV_MONITOR_KERNEL) {
struct udev_device* dev = udev_device_new_from_syspath(udev, "/sys" + nlmsg_ptr(nh), "usb_device");
if (dev != NULL) {
const char* action = udev_device_get_action(dev);
if (strcmp(action, "add") == 0) {
const char* devpath = udev_device_get_devpath(dev);
const char* subsystem = udev_device_get_subsystem(dev);
const char* devtype = udev_device_get_devtype(dev);
const char* id_vendor = udev_device_get_sysattr_value(dev, "idVendor");
const char* id_product = udev_device_get_sysattr_value(dev, "idProduct");
const char* serial = udev_device_get_sysattr_value(dev, "serial");
const char* devname = udev_device_get_devnode(dev);
printf("USB device added:\n");
printf(" DevPath: %s\n", devpath);
printf(" Subsystem: %s\n", subsystem);
printf(" DevType: %s\n", devtype);
printf(" Vendor ID: %s\n", id_vendor);
printf(" Product ID: %s\n", id_product);
printf(" Serial: %s\n", serial);
printf(" Device Name: %s\n", devname);
}
udev_device_unref(dev);
}
}
ptr += NLMSG_ALIGN(nh->nlmsg_len);
}
// receive inotify event
n = read(inotify_fd, &event, sizeof(event));
if (n == -1) {
perror("read");
continue;
}
// check inotify event
if (event.mask & IN_CREATE) {
// device is mounted
snprintf(name, MAX_NAME_SIZE, "/dev/%s", event.name);
printf("USB device mounted: %s\n", name);
} else if (event.mask & IN_DELETE) {
// device is unmounted
snprintf(name, MAX_NAME_SIZE, "/dev/%s", event.name);
printf("USB device unmounted: %s\n", name);
}
}
// cleanup
inotify_rm_watch(inotify_fd, watch_fd);
close(inotify_fd);
close(sockfd);
return 0;
}
```
需要注意的是,这个程序只是一个简单的示例,可能需要根据实际情况进行修改和优化。例如,需要添加错误处理、异常情况处理等功能。
阅读全文