繁体   English   中英

链接.a编译的库和自己的共享库Android NDK r8b

[英]Linking .a compiled library and own shared library Android NDK r8b

我在使用Android NDK r8b链接Android项目中的C库时遇到问题。 我使用ARM的工具链构建了cURL库(没有SSL),它为我提供了一个libcurl.a文件和一个libcurl.so.4.2.0。 我还创建了一个C文件来为Java代码提供功能并使用cURL库。

Android.mk

LOCAL_PATH:= $(call my-dir)

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

include $(CLEAR_VARS)
LOCAL_MODULE := curljni
LOCAL_SRC_FILES := curljni.c
LOCAL_STATIC_LIBRARIES := libcurl
include $(BUILD_SHARED_LIBRARY)

现在我的C文件

#include <string.h> 
#include <jni.h> 
#include <stdio.h> 
#include <stdlib.h> 

jstring Java_test_curljni_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz) 
{ 
  CURL *curl; 
  CURLcode 
......
}

当我尝试从项目文件夹中使用ndk-build命令进行构建时,这是输出错误:

Compile thumb  : curljni <= curljni.c
jni/curljni.c: In function 'Java_test_curljni_MainActivity_stringFromJNI':
jni/curljni.c:8:3: error: unknown type name 'CURL'
jni/curljni.c:9:3: error: unknown type name 'CURLcode'
jni/curljni.c:11:8: warning: assignment makes pointer from integer without a cast [enabled by default]
jni/curljni.c:13:28: error: 'CURLOPT_URL' undeclared (first use in this function)
jni/curljni.c:13:28: note: each undeclared identifier is reported only once for each function it appears in
/cygdrive/c/android-ndk-r8b/build/core/build-binary.mk:252: recipe for target `obj/local/armeabi/objs/curljni/curljni.o' failed
make: *** [obj/local/armeabi/objs/curljni/curljni.o] Error 1

我在Android.mk文件中尝试了很多事情,但没有成功。 使用PREBUILT_SHARED_LIBRARY并没有帮助,因为它只需要一个.so文件,并将扩展名从.so.4.2.0更改为.so,仅告诉我在构建时不支持该格式。

我不确定是否需要在C文件中包含标头,但是当我这样做时,它当然找不到它们。

注意,当我仅使用在Android.mk文件中声明的curl库进行构建时(省略了与C文件的共享库),那么libs文件夹中将不会创建任何内容!

在此先感谢您的帮助 !

编辑::::

实际上它确实可以工作mbrenon(我已经尝试了数百万次,现在它可以工作了,不知道有什么不同),但是现在我有了

c:/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6.x-google/../../../.                                     ./arm-linux-androideabi/bin/ld.exe: cannot find ./obj/local/armeabi/libcurl.a: Permission denied

我正在使用Cygwin,这可能就是为什么我遇到权限问题吗? 创建.so和.a时,我设法解决了这个问题,返回了权限错误,在其上执行chmod并再次运行ndk-build,但这似乎有些粗糙! 另外,现在我的curl函数都无法使用(“对(函数)的未定义引用”)。

$ ../../../ndk-build
SharedLibrary  : libcurljni.so
./obj/local/armeabi/objs/curljni/curljni.o: In function `Java_test_curljni_MainActivity_stringFromJNI':
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:12: undefined reference to `curl_easy_init'
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:14: undefined reference to `curl_easy_setopt'
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:15: undefined reference to `curl_easy_perform'
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:17: undefined reference to `curl_easy_cleanup'
collect2: ld returned 1 exit status
/cygdrive/c/android-ndk-r8b/build/core/build-binary.mk:378: recipe for target `obj/local/armeabi/libcurljni.so' failed
make: *** [obj/local/armeabi/libcurljni.so] Error 1

而我的curljni.c是以下

jstring Java_test_curljni_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz) 
{ 
  CURL *curl; 
  CURLcode res; 
  char buffer[10]; 
  curl = curl_easy_init(); 
  if(curl) { 
  curl_easy_setopt(curl, CURLOPT_URL, "yahoo.com"); 
  res = curl_easy_perform(curl); 
  curl_easy_cleanup(curl); 
  if(res == 0) 
     return (*env)->NewStringUTF(env, "0 response"); 
  else 
     sprintf(buffer,"code: %i",res); 
  return (*env)->NewStringUTF(env, buffer); 
  } 
  else { 
     return (*env)->NewStringUTF(env, "no curl"); 
  } 
} 

我确保在curl.h中声明了每个需要的功能

是的,您必须在C文件中包含Curl标头。 为了允许ndk-build在链接时找到这些头文件,您必须使用LOCAL_EXPORT_C_INCLUDES添加它们的路径:

include $(CLEAR_VARS)
LOCAL_MODULE:= libcurl
LOCAL_SRC_FILES := libcurl.a
LOCAL_EXPORT_C_INCLUDES := /* put the path to the Curl headers here */
include $(PREBUILT_STATIC_LIBRARY)

这将自动将路径添加到需要libcurl的所有目标中的标头中,并且应进行构建和链接。

暂无
暂无

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

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