Android ndk-build 链接器找不到预建库函数
Android ndk-build linker fails to find prebuilt library function
我正在尝试修改本教程以在我的 Android Studio 项目中包含预构建的 C 库(即不使用实验性 Gradle 插件)http://kvurd.com/blog/compiling-a-cpp-library-for-android-with-android-studio/
库本身来自一个不会透露源代码的客户,因此我无法控制构建过程的那一部分,但是他们已经在遵循相同的教程。
项目构建,load-library 工作并且 NDK link (/jni/my-wrapper.c) 工作正常,直到我尝试调用我的预构建中定义的实际库函数 header。我收到的错误是:
$ ndk-build
[arm64-v8a] Compile : my-wrapper <= my-wrapper.c
[arm64-v8a] SharedLibrary : libmy-wrapper.so
/Users/me/AndroidStudioProjects/MyProject/app/obj/local/arm64-v8a/objs/my-wrapper/my-wrapper.o: In function `Java_com_my_project_SignInActivity_CallFunction':
/Users/me/AndroidStudioProjects/MyProject/app/jni/my-wrapper.c:44: undefined reference to `MyFunction'
collect2: error: ld returned 1 exit status
make: *** [/Users/me/AndroidStudioProjects/MyProject/app/obj/local/arm64-v8a/libmy-wrapper.so] Error 1
这是我的 Android.mk:
LOCAL_PATH := $(call my-dir)
# static library info
include $(CLEAR_VARS)
LOCAL_MODULE := libMyLib
LOCAL_MODULE_FILENAME := libMyLib
LOCAL_SRC_FILES := ../prebuild/libMyLib.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include
include $(PREBUILT_STATIC_LIBRARY)
# wrapper info
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += ../prebuild/include
LOCAL_MODULE := my-wrapper
LOCAL_SRC_FILES := my-wrapper.c
LOCAL_STATIC_LIBRARIES := libMyLib
include $(BUILD_SHARED_LIBRARY)
和 MyLib.h(请注意 foobar() 在 header 中工作正常,但只要我从 my-wrapper.c 中调用 MyFunction ndk-build失败):
#include <math.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int MyFunction(some stuff);
int foobar(){return 1;};
最后,my-wrapper.c:
#include <MyLib.h>
jbyte Java_com_my_project_SignInActivity_MyFunction(JNIEnv *env, jobject thiz, some other stuff){
// return MyFunction(some other stuff which I cast to C types); //linker fails if uncommented
return foobar(); //works fine
}
这是一个 C++ 损坏的名称。您只能在 C++ 中使用它,而不能在 C 中使用。
如果你真的需要从 C 调用它,你可以这样做:
extern int _Z12MyFunctionP9my_structPhS1_S1_(/* whatever the function args are */);
jbyte Java_com_my_project_SignInActivity_MyFunction(
JNIEnv *env, jobject thiz, some other stuff) {
return _Z12MyFunctionP9my_structPhS1_S1_(args);
}
这取决于您调用的代码是否兼容(如果是这种情况,您应该要求客户将他们的 API 构建为 extern "C"
)。
不过,我真的建议您将代码移至 C++。
我正在尝试修改本教程以在我的 Android Studio 项目中包含预构建的 C 库(即不使用实验性 Gradle 插件)http://kvurd.com/blog/compiling-a-cpp-library-for-android-with-android-studio/
库本身来自一个不会透露源代码的客户,因此我无法控制构建过程的那一部分,但是他们已经在遵循相同的教程。
项目构建,load-library 工作并且 NDK link (/jni/my-wrapper.c) 工作正常,直到我尝试调用我的预构建中定义的实际库函数 header。我收到的错误是:
$ ndk-build
[arm64-v8a] Compile : my-wrapper <= my-wrapper.c
[arm64-v8a] SharedLibrary : libmy-wrapper.so
/Users/me/AndroidStudioProjects/MyProject/app/obj/local/arm64-v8a/objs/my-wrapper/my-wrapper.o: In function `Java_com_my_project_SignInActivity_CallFunction':
/Users/me/AndroidStudioProjects/MyProject/app/jni/my-wrapper.c:44: undefined reference to `MyFunction'
collect2: error: ld returned 1 exit status
make: *** [/Users/me/AndroidStudioProjects/MyProject/app/obj/local/arm64-v8a/libmy-wrapper.so] Error 1
这是我的 Android.mk:
LOCAL_PATH := $(call my-dir)
# static library info
include $(CLEAR_VARS)
LOCAL_MODULE := libMyLib
LOCAL_MODULE_FILENAME := libMyLib
LOCAL_SRC_FILES := ../prebuild/libMyLib.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include
include $(PREBUILT_STATIC_LIBRARY)
# wrapper info
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += ../prebuild/include
LOCAL_MODULE := my-wrapper
LOCAL_SRC_FILES := my-wrapper.c
LOCAL_STATIC_LIBRARIES := libMyLib
include $(BUILD_SHARED_LIBRARY)
和 MyLib.h(请注意 foobar() 在 header 中工作正常,但只要我从 my-wrapper.c 中调用 MyFunction ndk-build失败):
#include <math.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int MyFunction(some stuff);
int foobar(){return 1;};
最后,my-wrapper.c:
#include <MyLib.h>
jbyte Java_com_my_project_SignInActivity_MyFunction(JNIEnv *env, jobject thiz, some other stuff){
// return MyFunction(some other stuff which I cast to C types); //linker fails if uncommented
return foobar(); //works fine
}
这是一个 C++ 损坏的名称。您只能在 C++ 中使用它,而不能在 C 中使用。
如果你真的需要从 C 调用它,你可以这样做:
extern int _Z12MyFunctionP9my_structPhS1_S1_(/* whatever the function args are */);
jbyte Java_com_my_project_SignInActivity_MyFunction(
JNIEnv *env, jobject thiz, some other stuff) {
return _Z12MyFunctionP9my_structPhS1_S1_(args);
}
这取决于您调用的代码是否兼容(如果是这种情况,您应该要求客户将他们的 API 构建为 extern "C"
)。
不过,我真的建议您将代码移至 C++。