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

NDK中如何使用fanotify监控/proc/pid/maps及CMakeLists配置

问题根源

  • linux/fanotify.h是内核层面的头文件,仅定义fanotify的结构体、常量宏,不包含用户态函数的封装,所以引入该头文件不会报错,但直接调用fanotify_init会找不到函数定义。
  • sys/fanotify.h是C标准库提供的用户态头文件,包含函数声明。Android使用的bionic C库从API 30(Android 11)才正式加入该头文件和对应的fanotify_init、fanotify_mark函数封装,minSdkVersion低于30或者NDK版本过旧都会找不到该头文件和函数。

解决方案

分两种场景适配:

场景1:仅需要兼容Android 11(API 30)及以上设备

直接用bionic提供的官方封装即可,配置如下:

  1. 确认使用的NDK版本 >= r21,项目minSdkVersion设置为30或更高
  2. 在CMakeLists.txt中添加对应配置:
cmake_minimum_required(VERSION 3.18.0)
project("your_project_name")

# 显式指定目标API级别为30
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__ANDROID_API__=30")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__ANDROID_API__=30")

add_library(
        your_native_lib
        SHARED
        your_native_source.cpp
)

target_link_libraries(
        your_native_lib
        log
        # fanotify函数已内置在libc中,无需额外链接依赖库
)
  1. 代码中直接引入#include <sys/fanotify.h>即可正常调用相关函数。

场景2:需要兼容Android 11以下版本

由于低版本bionic没有封装fanotify函数,可直接通过系统调用调用内核功能,只要运行设备的内核版本 >= 2.6.36(绝大多数现役Android设备都满足)即可正常使用:

  1. 代码中引入内核头文件和系统调用头文件,自行封装fanotify函数:
#include <linux/fanotify.h>
#include <sys/syscall.h>
#include <unistd.h>

// 自行封装fanotify_init
static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags)
{
    return syscall(__NR_fanotify_init, flags, event_f_flags);
}

// 自行封装fanotify_mark
static inline int fanotify_mark(int fanotify_fd, unsigned int flags, 
                                __u64 mask, int dirfd, const char *pathname)
{
    return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, dirfd, pathname);
}
  1. 该场景下CMakeLists.txt无需额外特殊配置,按原有NDK项目配置正常编译即可。

额外注意事项

fanotify需要进程持有CAP_SYS_ADMIN权限才能正常调用,普通应用无该权限,运行时会返回权限错误,需要应用为系统应用、或者设备root后授予对应权限才可正常使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:54:04