2012-07-15 12 views
6

में संस्करणीकृत साझा लाइब्रेरी के साथ लिंक करना मैं loadLibrary कॉल के माध्यम से मेरी Android एप्लिकेशन में दो साझा पुस्तकालयों लोड करने के लिए कोशिश कर रहा हूँ:एंड्रॉयड NDK

System.loadLibrary("mywrapper"); 
System.loadLibrary("crypto"); 

मैं पकड़ने `UnsatisfiedLinkError प्रदर्शन जारी रहे। त्रुटि का एक और विस्तृत संस्करण यहां दिया गया है।

Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1969]: 
    130 could not load needed library 'libcrypto.so.1.0.0' for 
    'libmywrapper.so' (load_library[1111]: Library 'libcrypto.so.1.0.0' not found) 

कोई विचार?

कुछ समय बिताने के बाद मुझे पता चला कि एंड्रॉइड संस्करणित पुस्तकालयों का समर्थन नहीं करता है। क्या किसी को भी एक ही समस्या का सामना करना पड़ा है?

उत्तर

2

ऐसा लगता है कि एंड्रॉइड के पास संस्करणित पुस्तकालयों को लोड करने में कोई समस्या है। हाथ में समस्या लाइब्रेरी के कारण मेरे नाम libcrypto.so.1.0.0 में थी। यहां तक ​​कि यदि आप लाइब्रेरी का नाम बदलते हैं और इसे एंड्रॉइड फ़ाइल में पूर्व-निर्मित साझा लाइब्रेरी के रूप में लोड करने का प्रयास करते हैं तो यह विफल हो जाता है। (ऐसा इसलिए होना चाहिए क्योंकि फ़ाइल में लाइब्रेरी का नाम किसी भी तरह एम्बेडेड है। और इसके साथ लिंक करने वाली कोई भी लाइब्रेरी होने की उम्मीद है एक ही नाम के साथ एक पुस्तकालय से जुड़ा हुआ)

मुझे उम्मीद है कि एंड्रॉइड में संस्करण नामों के साथ पुस्तकालयों को संभालने के लिए वहां अन्य तरीके हैं।

अभी के लिए मैं openssl की स्थिर पुस्तकालयों का उपयोग करके और अपनी साझा लाइब्रेरी से लिंक करके सभी समस्याओं को एक साथ निकाल रहा हूं।

2

वर्ष 2014 और संस्करणित साझा libs के लिए अभी भी कोई समर्थन नहीं है। इसलिए मैंने सोनम को पैच करने के लिए एक स्क्रिप्ट बनाई। बस स्क्रिप्ट को इनपुट करने के लिए इंगित करें जहां सभी संस्करणित libs रखा गया है। फिर आउटपुट डीआईआर "अनवर" की जांच करें।

#!/bin/bash 

DIR="$1" 

if [ "$DIR" == "" ]; then 
    echo "Usage: fix-soname.sh <target dir>" 
    exit 
fi 

if [ ! -d $DIR ]; then 
    echo "Not found: $DIR" 
    exit 
fi 

OUT="$DIR/unver" 
echo "Input=$DIR" 
echo "Output=$OUT" 

CWD=$(pwd) 
cd $DIR 

# prep dirs 
mkdir -p $OUT 
rm -f -R $OUT/* 

# rename libs and copy to out dir 
find "$DIR" -type f -name '*.so*' | while read FILE; do 

    NAME=$(basename "$FILE") 
    SONAME=$NAME 

    while read SYMLINK; do 
     X=$(basename "$SYMLINK") 
     #echo "$X (${#X}) -> $NAME (${#NAME})" 
     if [ "${#X}" -lt "${#SONAME}" ]; then 
      SONAME=$X 
     fi 
done<<EOT 
`find -L $DIR -samefile $FILE` 
EOT 

    #echo $SONAME 
    cp -f $SONAME $OUT/ 
done 

# patch libs in out dir 
find "$OUT" -type f -name '*.so*' | while read FILE; do 

    # get file name without path 
    NAME=$(basename "$FILE") 

    # extract SONAME from shared lib 
    SONAME=`readelf -d $FILE | grep '(SONAME)' | grep -P '(?<=\[)(lib.*?)(?=\])' -o` 

    #echo "$NAME [$SONAME]" 

    # patch SONAME if required 
    if [ "$NAME" != "$SONAME" ]; then 
     L1=${#NAME} 
     L2=${#SONAME} 
     LDIFF=$((L2-L1)) 
     #echo "$NAME [$SONAME] ($LDIFF)" 

     if [ "$LDIFF" -gt "0" ]; then 
      SONEW=$NAME 
      for ((c=1; c<=$LDIFF; c++)); do 
       SONEW+="\x00" 
      done 
      echo "$NAME [$SONAME] -> $SONEW ($LDIFF)" 
      rpl -R -e "$SONAME" "$SONEW" $OUT 
     fi 
    fi 
done 

cd $CWD 
+0

यह मेरे लिए काम नहीं किया ... मैं openssl स्रोत निर्देशिका पर भाग गया, बाइनरी संकलित और 'Unver' dir उत्पादन exactaly – Giovani

+0

libcrypto.so मूल बाइनरी आप लिपि में #echo uncomment कर सकते हैं के रूप में ही है साथ और देखें कि कुछ गलत कहां जाता है। – sviborg

+0

या इसे ठीक करने के लिए [patchelf] (https://www.mankier.com/1/patchelf) का उपयोग करें। –

4

मुझे एंड्रॉइड के लिए libwebsockets बनाने पर एक ही समस्या थी, जिसे ओपनएसएसएल से जोड़ने की आवश्यकता है। मैं उदाहरण के रूप में libssl.so का उपयोग करें। आपको संबंधित .so फ़ाइलों के लिए भी ऐसा ही करना चाहिए।

Before: 
 
[email protected]:~$ objdump -p libssl.so | grep so 
 
libssl.so:  file format elf32-little 
 
    NEEDED    libcrypto.so.1.0.0 
 
    NEEDED    libdl.so 
 
    NEEDED    libc.so 
 
    SONAME    libssl.so.1.0.0 
 

 
After 
 
[email protected]:~$ rpl -R -e .so.1.0.0 "_1_0_0.so" libssl.so 
 
Replacing ".so.1.0.0" with "_1_0_0.so" (case sensitive) (partial words matched) 
 
. 
 
A Total of 2 matches replaced in 1 file searched. 
 
[email protected]:~$ objdump -p libssl.so | grep so 
 
libssl.so:  file format elf32-little 
 
    NEEDED    libcrypto_1_0_0.so 
 
    NEEDED    libdl.so 
 
    NEEDED    libc.so 
 
    SONAME    libssl_1_0_0.so 
 

 
And don't forget to change file name "libssl.so" to "libssl_1_0_0.so".

हैक काम करता है। मैं इसे साबित करने के लिए एंड्रॉइड ऐप चला रहा हूं। http://computervisionandjava.blogspot.com/2015/05/trouble-with-versioned-shared-libraries.html पर मेरा रेंट देखें।

+0

मैं .so फ़ाइलों के साथ काम करने के लिए आरपीएल प्राप्त करने में सक्षम नहीं था, लेकिन मैं सिर्फ वीआईएम के साथ फ़ाइल को संपादित करने में सक्षम था और वहां स्ट्रिंग को प्रतिस्थापित करता था। ग्रेट हैक। धन्यवाद! – Xample

संबंधित मुद्दे