Visual Studio 2017 Android NDK下math.h/cmath函数无法识别问题求助
我之前在VS2017搭配NDK r13b移植OpenGL ES代码时,也遇到过几乎一模一样的问题,给你几个亲测有效的解决方向:
强制使用std命名空间调用函数
因为C标准库的cmath函数默认在std命名空间下,NDK的gnu-libstdc 4.9实现尤其严格。比如把sqrt(x)改成std::sqrt(x),acos(y)改成std::acos(y),这样能直接绕过命名空间查找的问题。如果不想每次都写std::,可以在文件开头加using namespace std;(不过全局命名空间不推荐在大型项目里用,临时测试没问题)。用extern "C"包裹math.h的包含
如果你是在C++文件里混用了C风格的math.h,可能会因为名字修饰(name mangling)导致函数找不到。试试这样包含:extern "C" { #include <math.h> }这样编译器会按照C语言的规则处理math.h里的函数声明,避免和C++的名字修饰冲突。
检查预定义宏是否冲突
去项目属性的「C/C++ -> 预处理器」里看看,有没有意外定义了_NO_MATH_DEFINES或者类似的宏——这类宏会隐藏math.h里的函数声明。另外,可以手动添加#define _GLIBCXX_USE_C99 1在包含cmath之前,强制让gnu-libstdc++暴露C99标准的数学函数。确认NDK配置的针对性
因为是跨平台项目,一定要确保你修改的是Android平台的配置:- 确认链接器的「附加依赖库」里的
m;是加在Android配置下,而不是Windows配置 - 检查「C/C++ -> 语言」里的C标准确实设置为C11(或更高),并且这个设置对Android平台生效
- 确认链接器的「附加依赖库」里的
考虑升级NDK版本(可选)
NDK r13b确实比较老旧了,和VS2017的clang 3.8集成可能存在一些兼容性小问题。如果项目允许,升级到r21及以上的NDK版本,不仅能解决这类头文件问题,还能获得更好的编译性能和兼容性(android-21的目标API级别依然被支持)。
我当时是通过给cmath函数加上std::前缀,同时确认预定义宏没有冲突解决的问题,你可以逐个尝试这些方法。
内容的提问来源于stack exchange,提问作者Eteru

