HarmonyOS 鸿蒙Next NDK的raw_file.h中OH_ResourceManager_GetRawFileDescriptor函数无法在C语言中使用

HarmonyOS 鸿蒙Next NDK的raw_file.h中OH_ResourceManager_GetRawFileDescriptor函数无法在C语言中使用 函数声明如下:

bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor);

这个声明是C++的声明,在C语言中使用编译会报错,要么就改声明,要么加一个宏判断来屏蔽C语言。

15 回复

尊敬的开发者,您好!感谢您的反馈,问题正在加速处理中,还请关注后续版本,感谢您的理解与支持。

更多关于HarmonyOS 鸿蒙Next NDK的raw_file.h中OH_ResourceManager_GetRawFileDescriptor函数无法在C语言中使用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


我前面补充的重点就是这个方向:raw_file.h 作为 C API 头文件,不应该让纯 C 编译器直接看到 RawFileDescriptor &descriptor 这种 C++ 引用参数声明。

比较合理的修复方式还是让官方在头文件层做兼容处理,比如把旧的引用参数接口放到 #ifdef __cplusplus 分支里,或者 C 侧只暴露指针参数版本。今天官方也已经回复“正在与系统侧沟通确认解决方案”,后续以系统侧修复为准。

应用侧临时规避仍建议:纯 C 文件不要直接依赖这个旧声明,优先改用 Data 后缀的 C 风格接口;如果当前 SDK 头文件 include 阶段就失败,就用一个 .cpp 桥接层封装 extern “C” 函数给 C 调用。

你说得对,我前面表达没有抓到重点。这个问题不是“接口废弃后还要不要用”,而是 raw_file.h 作为 C API 头文件时出现了 C++ 引用参数 RawFileDescriptor &descriptor,导致纯 C 编译器在包含头文件阶段就可能解析失败。

从头文件兼容性角度看,官方更合理的修复方向有两个:一是把旧的引用参数声明放到 #ifdef __cplusplus 里,只暴露给 C++;二是 C 侧只暴露指针参数版本,也就是 OH_ResourceManager_GetRawFileDescriptorData(const RawFile *rawFile, RawFileDescriptor *descriptor) 和 ReleaseRawFileDescriptorData。

应用侧临时规避可以这样做:C 文件里不要直接依赖旧的引用参数接口,优先改用 Data 后缀的 C 风格接口;如果当前 SDK 的 raw_file.h 仍因为旧声明导致 C 编译失败,可以在一个 .cpp 文件里包含 raw_file.h 并封装一层 extern “C” 的桥接函数给 C 调用,或者把相关调用文件改成 C++ 编译单元。

这个更像头文件导出兼容性/文档归类问题,建议同时走文档反馈或工单,让官方确认是否需要在头文件里加 __cplusplus 条件保护。

这回说到重点了,就应该加个宏来过滤一下。

尊敬的开发者,您好, 关于您反馈的问题,当前bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor);已废弃 请改用 bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor *descriptor);

大哥,请仔细看我的问题,我不是问你是否已经废弃,是说你这个代码在C语言下编译会报错,建议你们官方添加一个宏判断来屏蔽C语言包含这个符号,如果你听不懂,请换更高级的技术支持来,谢谢。

你怎么不说话了?

尊敬的开发者,您好!您的问题已受理,请您耐心等待,感谢您的理解与支持!

该问题正在与系统侧沟通确认解决方案,请您耐心等待一下

这个问题本质上就是:

RawFileDescriptor &descriptor

用了 C++ 引用语法:

&

但头文件:

raw_file.h

又暴露给了 C 使用,所以纯 C 编译器会直接报错。

因为:

C语言不支持引用

所以目前这个接口实际上只能在:

.cpp

环境里使用。


目前有几个方案:

1、直接改成 C 风格接口(最合理)

例如:

bool OH_ResourceManager_GetRawFileDescriptor(
    const RawFile *rawFile,
    RawFileDescriptor *descriptor
);

这样:

  • C
  • C++
  • NDK

都能正常使用。


2、官方加宏区分 C/C++

类似:

#ifdef __cplusplus
extern "C" {
#endif

或者:

#ifdef __cplusplus
bool xxx(RawFileDescriptor &descriptor);
#else
bool xxx(RawFileDescriptor *descriptor);
#endif

3、当前临时解决方案

如果你现在必须在 C 工程里用:

只能:

  • .cpp
  • extern "C"
  • 再包一层 C 接口

例如:

// wrapper.cpp

extern "C" bool My_GetRawFileDescriptor(
    const RawFile *rawFile,
    RawFileDescriptor *descriptor
) {
    return OH_ResourceManager_GetRawFileDescriptor(
        rawFile,
        *descriptor
    );
}

然后 C 里调用你自己的包装函数。


所以这个确实算是:

NDK头文件兼容性问题

理论上官方应该:

  • 改成指针参数
  • 或增加 C/C++ 条件编译

否则这个接口名义上是 NDK,实际上只能 C++ 使用。

类似的问题还很多 建议避免使用。这个问题我提过两三年了 官方不会改~

完全可以加个宏判断来屏蔽C语言包含这个函数声明呀,这么简单的问题官方都想不到吗?

这个接口建议不要再在 C 代码里直接用了。文档里 OH_ResourceManager_GetRawFileDescriptor(const RawFile*, RawFileDescriptor&) 是 API 12 已废弃接口,参数里的 & 本来就是 C++ 引用,所以 C 编译会报错。

C 工程可以改用替代接口:OH_ResourceManager_GetRawFileDescriptorData(const RawFile*, RawFileDescriptor*),释放时对应 OH_ResourceManager_ReleaseRawFileDescriptorData(const RawFileDescriptor*)。大致写法是先定义 RawFileDescriptor desc,然后传 &desc;使用完一定释放,避免 fd 泄漏。

如果项目里还需要兼容老接口,建议在 C++ 文件里包一层适配函数,C 侧头文件只暴露指针参数,不建议直接改 SDK 头文件。

完全可以加个宏判断来屏蔽C语言包含这个函数声明呀。

OH_ResourceManager_GetRawFileDescriptor 在 HarmonyOS Next NDK 中已不再向 C 语言暴露,其实现仅面向 ArkTS/TS 或 C++ 层开放。该接口的 ABI 符号在 C 语言编译环境下被移除,因此无法直接链接或调用。

该函数声明使用了C++的引用类型 RawFileDescriptor &descriptor,而引用是C语言不支持的语法,因此在C编译环境下会直接报错。当前 raw_file.h 头文件未使用 extern "C"__cplusplus 宏区分C/C++声明,也未提供纯C的指针传递版本。

临时解决方法

  • 若允许使用C++编译,将调用方的 .c 文件改为 .cpp 即可。
  • 若必须在C中调用,可自建一个C++包装函数,导出为C接口(指针版),例如:
#ifdef __cplusplus
extern "C" {
#endif
bool OH_ResourceManager_GetRawFileDescriptor_C(const RawFile *rawFile, RawFileDescriptor *descriptor);
#ifdef __cplusplus
}
#endif
// C++实现中调用原函数
bool OH_ResourceManager_GetRawFileDescriptor_C(const RawFile *rawFile, RawFileDescriptor *descriptor) {
    return OH_ResourceManager_GetRawFileDescriptor(rawFile, *descriptor);
}

然后在C代码中包含包装后的声明即可。

本质原因:NDK头文件在设计时未兼顾纯C用户的调用场景,缺少C兼容宏保护及对应的指针重载版本。建议将此问题反馈至HarmonyOS官方Issue或SDK意见收集渠道,推动后续版本修复。

回到顶部