简体   繁体   English

Android ndk-build链接器无法找到预构建的库函数

[英]Android ndk-build linker fails to find prebuilt library function

I'm trying to modify this tutorial to include a prebuilt C library in my Android Studio project (ie. not using the experimental Gradle plugin) http://kvurd.com/blog/compiling-a-cpp-library-for-android-with-android-studio/ 我正在尝试修改本教程,以在我的Android Studio项目中包含一个预建的C库(即,不使用实验性Gradle插件) http://kvurd.com/blog/compiling-a-cpp-library-for-android -with-android-studio /

The library itself is coming from a client who won't reveal the source code, therefore I have no control over that part of the build process, however they are already following the same tutorial. 该库本身来自不会透露源代码的客户端,因此我无法控制构建过程的那部分,但是它们已经遵循了同一教程。

The project builds, load-library works and the NDK link (/jni/my-wrapper.c) works fine, until I try to call the actual library function defined in my prebuild header. 项目构建,加载库工作以及NDK链接(/jni/my-wrapper.c)都可以正常工作,直到我尝试调用在prebuild标头中定义的实际库函数为止。 The error I'm receiving is: 我收到的错误是:

$ 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

Here's my Android.mk: 这是我的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)

And MyLib.h (note that foobar() works fine as it's in the header but as long as I'm calling MyFunction from within my-wrapper.c the ndk-build fails): 和MyLib.h(注意foobar()可以在标头中正常工作,但是只要我从my-wrapper.c内部调用MyFunction,ndk生成就会失败):

#include <math.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int MyFunction(some stuff);
int foobar(){return 1;};

Finally, my-wrapper.c: 最后,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
}

That's a C++ mangled name. 那是C ++杂乱的名字。 You can only use it from C++, not from C. 您只能从C ++使用它,而不能从C使用它。

If you really need to call it from C, you might be able to do it like so: 如果确实需要从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);
}

That depends on the code you're calling being compatible as such (if that's the case, you should ask the client to build their APIs as extern "C" ). 这取决于您要调用的代码本身是否兼容(如果是这种情况,则应要求客户端将其API构建为extern "C" )。

I'd really recommend just moving your code to C++ though. 我真的建议您不过将代码移至C ++。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM