4

AndroidNDKr8bを使用してAndroidプロジェクトでCライブラリをリンクする際に問題が発生します。ARM用のツールチェーンを使用してcURLライブラリ(SSLなし)を構築しました。これにより、libcurl.aファイルとlibcurl.so.4.2.0ファイルが提供されました。また、Javaコードに関数を提供し、cURLライブラリを使用するためのCファイルも作成しました。

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フォルダーには何も作成されません。

よろしくお願いします!

編集 ::::

実際には動作しました(私は何百万回も試しましたが、今は動作しますが、何が違うのかわかりません)が、今は

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を再度実行しますが、それは少しラフに思えます!さらに、現在、私のカール関数には到達できません(「(関数)への未定義の参照」)。

$ ../../../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で宣言されていることを確認しました

4

1 に答える 1

2

はい、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 を必要とするすべてのターゲットのヘッダーへのパスが自動的に追加され、ビルドしてリンクする必要があります。

于 2012-11-13T10:00:43.183 に答える