Android NDK C ++ JNI (لم يتم العثور على تنفيذ لـ Native ...)

StackOverflow https://stackoverflow.com/questions/2197889

  •  25-09-2019
  •  | 
  •  

سؤال

أحاول استخدام NDK مع C ++ ولا يمكنني الحصول على صحة اتفاقية تسمية الطريقة. طريقتي الأصلية على النحو التالي:

extern "C" {
JNIEXPORT void JNICALL Java_com_test_jnitest_SurfaceRenderer_drawFromJni
(JNIEnv* env, jclass c)
{
   //
}
}

مع رأس ملفوف في extern "c" {} aslo.

كل شيء يتجمع بشكل جيد ، ويقوم بإنشاء ملف. لذا ، يقوم بنسخ إلى مجلد LIBS ضمن مشروعي ، لكن عندما أقوم بتصحيح وأركض في Eclipse ، أستمر في الحصول على رسالة قطة سجل "لم يتم العثور على تنفيذ لـ Native ...". هل هناك شيء أفتقده لأن جميع أمثلة NDK في C؟

شكرًا.

هل كانت مفيدة؟

المحلول

هناك بعض الأشياء التي يمكن أن تؤدي إلى "عدم وجود تنفيذ". واحد هو الحصول على اسم النموذج الأولي الخاطئ ، والآخر هو فشل في تحميل. لذلك على الإطلاق. هل انت متاكد من System.loadLibrary() هل يتم استدعاؤه قبل استخدام الطريقة؟

إذا لم يكن لديك JNI_OnLoad الوظيفة المحددة ، قد ترغب في إنشاء واحدة وجعلها تبصق رسالة سجل فقط للتحقق من أن LIB يتم سحبها بنجاح.

لقد تهربت بالفعل المشكلة الأكثر شيوعًا - نسيت الاستخدام extern "C" - لذلك فهو إما ما سبق أو بعض الأخطاء الخفيفة. كيف يبدو إعلان جافا؟

نصائح أخرى

سبب إضافي لهذا الخطأ: يجب ألا يحتوي اسم الطريقة الأصلية غير الموروثة على السطح السفلي!

على سبيل المثال ، أردت تصدير وظيفة C المسمى AudioCapture_Ping(). إليكم إعلان التصدير في ج:

JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapture_Ping(JNIEnv *pJniEnv, jobject object);  //Notice the underscore before Ping

هنا كان فئة Java الخاصة بي تستورد الوظيفة:

package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
    private native int AudioCapture_Ping();  // FAILS
    ...

لم أتمكن من الحصول على Android للربط ديناميكيًا بطريقتي الأصلية حتى أزلت السطح السفلي:

JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapturePing(JNIEnv *pJniEnv, jobject object); 

package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
    private native int AudioCapturePing();  // THIS WORKS!
    ...

واجهت نفس المشكلة ، لكن بالنسبة لي كان الخطأ في ملف Android.mk. كان لي:

LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES := B.cpp 

ولكن يجب أن يكون هذا:

LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES += B.cpp 

لاحظ التفاصيل += في حين أن :=

أتمنى أن يساعد ذلك.

يسمى Extern "C" كما هو منصوص عليه في مثال الاستوديو الذي تم إنشاؤه تلقائيًا ، ولكن نسيت لف بقية الملف بأكمله ، بما في ذلك الوظائف التالية ، بين قوسين {}. فقط الوظيفة الأولى عملت.

سبب إضافي: استخدم local_whole_static_libraries بدلاً من local_static_libraries في Android.mk. هذا يمنع المكتبة من تحسين مكالمات API غير المستخدمة لأن NDK لا يمكنه اكتشاف استخدام الارتباطات الأصلية من رمز Java.

استخدم Javah (جزء من Java SDK). إنها الأداة بالضبط لهذا (توليد رأس .H من ملف .class).

إذا كان اسم الحزمة الخاص بك يتضمن _ حرفًا ، فيجب عليك كتابة 1 (واحد) بعد _ الحرف كما هو موضح أدناه:

MainActivity.Java

package com.example.testcpp_2;

الأصلي lib.cpp

JNICALL
Java_com_example_testcpp_12_MainActivity_stringFromJNI(

أحاول جميع الحلول المذكورة أعلاه ، ولكن لا يمكن لأحد أن يحل خطأ البناء الخاص بي (Jni java.lang.unsatisfiedlinkerror: لم يتم العثور على تنفيذ لـ ...) ، في النهاية وجدت أنني نسيت إضافة ملف مصدر Verify.cpp الخاص بي إلى cmakelist.txt ADD_LIBRARY SEGEMENT (تحقق.

بيئة البناء الخاصة بي: Gradle + Cmake

واجهت نفس المشكلة ، وفي حالتي كان السبب في أنني قد أكدت في اسم الحزمة "RFID_TEST" أعيد تسمية الحزمة وعملت. شكرا user1222021

واجهت نفس المشكلة مرتين. حدث ذلك ، أن الهاتف حاولت بدء التطبيق من Android Studio يستخدم مستوى API أنني لم أقم بتنزيلها بعد في Android Studio.

  1. ترقية Android Studio إلى أحدث إصدار
  2. قم بتنزيل واجهة برمجة التطبيقات اللازمة من داخل Android Studio
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top