2011-06-14 11 views
6

मैं एंड्रॉइड में एक साधारण जेनी कोड चलाने की कोशिश कर रहा हूं, लेकिन मुझे सभी को असंतुष्ट लिंक मिल रहा है।एंड्रॉइड में असंतुष्टलिंकिंकर (ग्रहण)

यहाँ मेरी जावा कोड है: यहाँ

package com.lipcap; 

import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 

public class MainActivity extends Activity { 
/** Called when the activity is first created. */ 

TextView a; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    a=new TextView(this); 

    String b; 
    MainActivity ob=new MainActivity(); 
    b=ob.sniff(); 

    a.setText(b); 

    setContentView(a); 
} 
public native String sniff(); 

    static{ 
     System.loadLibrary("native"); 
    } 


} 

और मेरे सी ++ कोड ($ PROJECT_PATH/में JNI /) है:

#include<iostream> 
#include<string.h> 
#include<jni.h> 
JNIEXPORT jstring JNICALL Java_com_lipcap_MainActivity_sniff 
(JNIEnv *env, jobject obj){ 
     return env->NewStringUTF("This is Native"); 
} 

मैं javac का उपयोग कर जावा कोड का पालन किया है, और बना दिया जावा का उपयोग कर हेडर।

तब मैं ndk-build चला गया। और फिर मैंने ग्रहण से कोड चलाया। (एंड्रॉइड में स्थापित एपीके)।

E/AndroidRuntime( 769): FATAL EXCEPTION: main 
E/AndroidRuntime( 769): java.lang.UnsatisfiedLinkError: sniff 
E/AndroidRuntime( 769): at com.lipcap.MainActivity.sniff(Native Method) 
E/AndroidRuntime( 769): at com.lipcap.MainActivity.onCreate(MainActivity.java:36) 
E/AndroidRuntime( 769): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
E/AndroidRuntime( 769): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
E/AndroidRuntime( 769): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
E/AndroidRuntime( 769): at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
E/AndroidRuntime( 769): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
E/AndroidRuntime( 769): at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 769): at android.os.Looper.loop(Looper.java:123) 
E/AndroidRuntime( 769): at android.app.ActivityThread.main(ActivityThread.java:4627) 
E/AndroidRuntime( 769): at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime( 769): at java.lang.reflect.Method.invoke(Method.java:521) 
E/AndroidRuntime( 769): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
E/AndroidRuntime( 769): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
E/AndroidRuntime( 769): at dalvik.system.NativeStart.main(Native Method) 

मैं LD_LIBRARY_PATH सेट नहीं किया है:

मैं इस त्रुटि मिलती है।

हालांकि, एनडीके द्वारा प्रदान की गई हैलोजेएनआई जैसे एलडी_LIBRARY_PATH नमूना कोड को सेट किए बिना बिल्कुल ठीक है।

कृपया मुझे बताएं कि मुझे कहां याद आ रही है।

+2

'MainActivity ओब = नई मुख्य गतिविधि(); क्यों? आप पहले से ही मुख्य क्रियाकलाप के उदाहरण में हैं। 'this.sniff()' का उपयोग किया जाना चाहिए। –

+1

हाँ, this.sniff का उपयोग किया जा सकता है। वैसे भी, इससे कोई फर्क नहीं पड़ता है जहां तक ​​असंतुष्टलिंक आतंक का संबंध है। – d34th4ck3r

+0

सी ++ से सी में कोड बदलना सब ठीक काम करता है .. :) – d34th4ck3r

उत्तर

0

यह वास्तव में बहुत सही नहीं बुलाया गया है ...

प्रयास करें:

package com.lipcap; 

import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 

public class MainActivity extends Activity { 
    /** Called when the activity is first created. */ 

    TextView a; 

    public native String sniff(); 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     a=new TextView(this); 

     String b = sniff(); 

     a.setText(b); 

     setContentView(a); 
    } 

    static{ 
     System.loadLibrary("native"); 
    } 

} 

अन्त में ... यह आपके Android.mk में है?

LOCAL_MODULE := native 
+0

Thanx, लेकिन इससे समस्या हल नहीं हुई। – d34th4ck3r

+0

संपादन की जांच करें ... एंड्रॉइड.एमके में मॉड्यूल का नाम आपके द्वारा लोड किए जा रहे लाइब्रेरी नाम से मेल खाना चाहिए। – Maximus

+0

इसके अलावा, घोषणा का आदेश जावा में कोई फर्क नहीं पड़ता। – d34th4ck3r

12

रिचर्ड सिर आपका उल्लेख किया: "सी सब कुछ करने के लिए C++ से कोड बदलने ठीक काम करता है" ...

मैं कई दिनों के लिए ठीक उसी समस्या से अत्याचार किया गया और मुझे यकीन है कि सब कुछ बनाने के लिए किया था मेरे द्वारा टाइप किया गया (नामकरण, एंड्रॉइड.एमके इत्यादि) कोई समस्या नहीं है। जब भी सी में, मैं ठीक हूँ। जब तक मैं सीपीपी में बदलता हूं, UnsatisfiedLinkErrorhttp://markmail.org/message/fhbnprmp2m7ju6lc

यह सब सी ++ नाम mangling की वजह से है:

मैं अंत में इस लिंक से संकेत मिल गया है! एक ही फ़ंक्शन, यदि आपके पास .cpp फ़ाइल में इसके आसपास extern "C" नहीं है, तो नाम उलझा हुआ है, इसलिए जेएनआई को फ़ंक्शन नाम नहीं मिल रहा है, इसलिए UnsatisfiedLinkError पॉप अप हो गया है।

extern "C" { } को अपने कार्यों के आस-पास रखें और हटाएं, nm obj/local/armeabi/libnative.so चलाएं, आप स्पष्ट रूप से नाम के बिना और बिना किसी फ़ंक्शन को स्पष्ट रूप से देखेंगे।

मुझे उम्मीद है कि यह दूसरों को भी एक ही समस्या के साथ मदद करता है।

0

मैं एक और सलाह दूंगा। मुझे यह वही त्रुटि मिली है, लेकिन मैंने "एंड्रॉइड नेटिव डेवलपमेंट किट कुकबुक" के माध्यम से इस समस्या को हल किया। कृपया इन बयानों को नोट करें;

देशी फ़ंक्शन को पैकेज नाम, कक्षा का नाम और विधि नाम के लिए एक विशिष्ट पैटर्न का पालन करना होगा। पैकेज और कक्षा का नाम जावा क्लास के पैकेज और क्लास नाम से सहमत होना चाहिए जिससे मूल विधि कहा जाता है, जबकि विधि का नाम उस जावा क्लास में घोषित विधि नाम के समान होना चाहिए। यह दलविक वीएम को रनटाइम पर देशी फ़ंक्शन का पता लगाने में मदद करता है। नियम का पालन करने के लिए विफल होने पर रनटाइम पर असंतुष्ट लिंक्स त्रुटि होगी।

उदाहरण के लिए के लिए

ऊपर

आप की तरह अपने कार्य का नाम बदलना चाहते (पैकेज के नाम में com.bla का उपयोग नहीं करते, तो आप NDK पर ध्यान केंद्रित)

#include<iostream> 
#include<string.h> 
#include<jni.h> 

JNIEXPORT jstring JNICALL Java_lipcap_example_MainActivity_sniff 
(JNIEnv *env, jobject obj){ 
     return env->NewStringUTF("This is Native"); 
} 
संबंधित मुद्दे