我该如何在Android NDK中使用complex.h?

8

我有一份用C语言编写的本地源代码,想要在我的Android设备(Nexus 7)上运行。我已经通过Android NDK成功进行了大量的研究和在线教程,学到了不少相关知识。 然而,我的代码使用了复杂功能库complex.h中定义的复杂数学函数。但是NDK C库似乎不支持这些复杂的功能。每当我在项目上执行ndk-build时,都会得到以下错误:

fatal error: complex.h: no such file or directory.

作为解决方案,我想从arm-linux-gnueabi获取标准math库(libm.a),并将其与我的本地源代码进行链接。这是我的Android.mk文件:
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := StandardC
LOCAL_SRC_FILES := libc.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := mathLib
LOCAL_SRC_FILES := libm.a
LOCAL_STATIC_LIBRARIES := StandardC
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := ComplexOperations
LOCAL_SRC_FILES := libComplexOperations.a
LOCAL_STATIC_LIBRARIES := mathLib
LOCAL_C_INCLUDES += /usr/arm-linux-gnueabi/include
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := MySource
LOCAL_CFLAGS += -std=c99
LOCAL_SRC_FILES := com_samuel_test_ComplexOperationsLib.c
LOCAL_C_INCLUDES += /usr/arm-linux-gnueabi/include
LOCAL_STATIC_LIBRARIES := ComplexOperations
include $(BUILD_SHARED_LIBRARY)

我需要链接arm-linux-gnueabi-gcc的libc以及libm,因为"ComplexOperations"模块使用了complex.h,并且该模块已经使用编译器标志-march=armv7-a进行了静态编译。这个库在编译时没有出现任何错误或警告,但是当我运行应用程序并调用它时,出现了问题。

System.loadLibrary("MySource");

我在logcat中看到了如下报错:

E/dalvikvm( 3932): dlopen("/data/app-lib/com.samuel.test-1/libMySource.so") failed: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol ".LANCHOR2" referenced by "libMySource.so"...

当出现这个错误时,会抛出UnsatisfiedLinkError异常,如果没有处理,应用程序将崩溃。

请有人帮帮我!!我已经尝试了好几天都没有解决!:(


1
安卓真的没有 complex.h 吗? - Stephen Canon
4个回答

3

1
我在Android.mk中添加了以下行,似乎已经解决了问题。
LOCAL_C_INCLUDES += C:\Users\Sami\workspace\android-ndk-r8e\sources\cxx-stl\gnu-libstdc++\4.7\include\

不确定哪个变量可以替换 C:\Users\Sami\workspace\,如果有人知道,请告诉我。


编辑:事实上,那只是因为某些原因移除了错误,但据我观察,并没有解决问题。在此提及,C:\Users\Sami\workspace\android-ndk-r8e 可以被替换为 $(NDK_ROOT)

我尝试了Crystax的NDK,但我一直收到找不到 complex.h 的错误。我所做的就是简单地将 complex.h 和 _mingw.h 复制到我的jni目录中。所有东西都正常工作并且代码已在x86和ARM模拟器上测试过。


0

问题已解决!

首先,我应该使用Android NDK提供的工具链构建我的ComplexOperations源代码,因为文档明确指出不要使用gnu编译器进行交叉编译。这是我的第一个错误。 但仅仅这样还不能解决我的问题,因为当我执行ndk-build时,仍然会出现complex.h找不到的错误。Android NDK包含非常有限的标准libc实现。 为了解决这个问题,我使用了CrystaX NDK,这是Android NDK的扩展实现。这解决了所有问题!


你是怎么解决这个问题的?你只是使用了CrystaX的交叉编译器吗? - JohnTortugo
虽然已经过了一段时间,但是如果我看一下我上面的回答,我使用了Android NDK的工具链进行交叉编译,并使用了CrystaX的Ndk-build工具。也许现在Android NDK的ndk-build工具支持complex.h库了。但如果不支持,那么CrystaX就可以胜任。祝你好运! - Sam
似乎只有g++有complex.h文件。我也在考虑CrystaX交叉编译器。无论如何,谢谢。 - JohnTortugo
你尝试过Sami Al-Terkawi Hasib在他的回答中描述的解决方案吗?他似乎已经解决了这个问题,而没有使用CrystaX。 - Sam
1
这些 NDK 中的 "complex.h" 文件似乎非常有限... 我用另一种方式解决了这个问题。谢谢你的帮助。 - JohnTortugo
@JohnTortugo...能否请您分享一下您是如何解决这个问题的? - stinepike

0

谢谢Yasir。但我的PATH没有损坏,因为编译器可以找到所有其他的头文件。只是NDK使用的编译器不支持应该在math库中定义的复杂操作。我想我已经通过将bionic math库与我的源代码链接来解决了这个问题,但现在我又遇到了链接错误的问题!我对库进行了objdump,并学习到.LANCHOR2在libc.a中定义,而我要链接我的源代码(请参见我的Android.mk)。我猜现在我应该找到一种方法将那个libc加载到android中。 - Sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接