You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu 16.04虚拟机下含内核头文件的GCC代码/Makefile编译求助

嘿,我来帮你搞定这个编译的问题!首先得先给你提个关键的点:你写的代码里直接访问dev_base这种内核空间的结构体和符号,在用户态程序里是没法正常运行的——毕竟内核空间和用户态是完全隔离的,用户态程序不能直接碰内核的内部数据结构和符号。不过我先告诉你怎么编译这类引用内核头文件的代码,再给你指条正确的用户态获取网卡信息的路子~

一、直接用GCC编译的指令

如果只是想先把代码编译通过(虽然运行会报错),你需要指定内核头文件的搜索路径。Ubuntu 16.04的内核头文件一般在/usr/src/linux-headers-$(uname -r)目录下,直接用这条指令编译:

gcc -o net_info net_info.c -I/usr/src/linux-headers-$(uname -r)/include -I/usr/src/linux-headers-$(uname -r)/arch/x86/include

简单解释下参数:

  • -I:用来告诉GCC额外的头文件搜索路径,因为内核头文件不在默认的搜索列表里
  • net_info.c是你的源代码文件名,net_info是编译后生成的可执行文件名称,你可以根据自己的需求修改
二、编写Makefile来自动化编译

如果不想每次都敲长指令,写个Makefile会方便很多。创建一个名为Makefile的文件,把下面的内容粘进去:

# 自动获取当前系统的内核头文件路径
KERNEL_HEADERS := /usr/src/linux-headers-$(shell uname -r)

# 定义可执行文件和源文件的名称
TARGET := net_info
SRC := net_info.c

# 编译选项,指定内核头文件的搜索路径
CFLAGS := -I$(KERNEL_HEADERS)/include -I$(KERNEL_HEADERS)/arch/x86/include

# 默认执行的编译目标
all: $(TARGET)

# 编译规则:从源文件生成可执行文件
$(TARGET): $(SRC)
    gcc $(CFLAGS) -o $@ $<

# 清理生成的可执行文件
clean:
    rm -f $(TARGET)

之后在终端里进入代码所在目录,敲make就能自动编译,敲make clean可以删掉生成的可执行文件。

三、重要提示:用户态获取网卡信息的正确姿势

刚才说了,你原来的代码在用户态跑不起来,因为dev_base是内核内部的符号,用户态程序根本访问不到。这里给你一个能用的示例代码,用标准的用户态API getifaddrs()来获取网卡名称和IP地址:

#include <stdio.h>
#include <stdlib.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main() {
    struct ifaddrs *ifap, *ifa;
    struct sockaddr_in *sa;
    char addr[INET_ADDRSTRLEN];

    // 获取所有网卡信息
    if (getifaddrs(&ifap) == -1) {
        perror("getifaddrs");
        exit(EXIT_FAILURE);
    }

    // 遍历每个网卡
    for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr == NULL)
            continue;
        // 只处理IPv4地址(如果需要IPv6可以加AF_INET6的判断)
        if (ifa->ifa_addr->sa_family == AF_INET) {
            sa = (struct sockaddr_in *)ifa->ifa_addr;
            inet_ntop(AF_INET, &sa->sin_addr, addr, INET_ADDRSTRLEN);
            printf("dev name: %s\nIP address: %s\n\n", ifa->ifa_name, addr);
        }
    }

    // 释放资源
    freeifaddrs(ifap);
    return 0;
}

这个代码就很省心了,直接用普通GCC指令编译就行:

gcc -o net_info net_info.c

运行./net_info就能看到所有网卡的名称和对应的IP地址啦~

内容的提问来源于stack exchange,提问作者user9692088

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:46:41