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

标签 android build android-ndk libraries

我在使用 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 函数(“对(函数)的 undefined reference ”)。

$ ../../../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 header 。要允许 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 的目标中的 header ,并且它应该构建和链接。

关于android - 链接.a编译库和自己的共享库Android NDK r8b,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13358052/

相关文章:

java - 访问 AutoCompleteTextView 的 CustomAdapter 中所选项目的值

android - 通过查询填充微调器

用于两个或多个 python 文件(模块)的 Python cx_Freeze

android - Linphone Android如何导入库项目?

java - 当 EditText 在 ListView 中时,selectAllOnFocus 的奇怪行为

java - 轻量级、可折叠的 Executor 实现?

c++ - 在开源社区构建 C/C++ 程序的最佳方式是什么?

ubuntu - 在 ubuntu 中运行 pcl/tools/mesh2pcd.cpp

android - Renderscript 致命信号 11 (SIGSEGV) 代码 1 (SEGV_MAPERR) 故障地址

android - SharedLib 依赖@混合模式 APK