Using jnigraphics in 2.1

841 views
Skip to first unread message

arraypad

unread,
May 27, 2011, 4:54:00 PM5/27/11
to android-ndk
Hi,

I'm having trouble using jnigraphics as a prebuilt shared library. My
Android.mk is as follows:

> LOCAL_PATH := $(call my-dir)
>
> include $(CLEAR_VARS)
>
> LOCAL_MODULE := jnigraphics-prebuilt
> LOCAL_SRC_FILES := lib/libjnigraphics.so
> LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
>
> include $(PREBUILT_SHARED_LIBRARY)
>
> include $(CLEAR_VARS)
>
> LOCAL_MODULE := yyy
> LOCAL_SRC_FILES := yyy.c
> LOCAL_SHARED_LIBRARY := jnigraphics-prebuilt
> LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
> LOCAL_LDLIBS += -lm -llog
> #LOCAL_CFLAGS += -O3
>
> include $(BUILD_SHARED_LIBRARY)

The output I get when I try ndk-build is:

> Prebuilt : libjnigraphics.so <= jni/lib/
> Install : libjnigraphics.so => libs/armeabi/libjnigraphics.so
> Compile thumb : yyy <= yyy.c
> SharedLibrary : libyyy.so
> /home/xxx/w/zzz/obj/local/armeabi/objs/yyy/yyy.o: In function `Java_yyy_yyy_yyy_MainActivity_yyy':
> /home/xxx/w/zzz/jni/yyy.c:143: undefined reference to `AndroidBitmap_getInfo'
> [many more undefined references]

I've experimented with various paths in LOCAL_LDLIBS with no luck. I
suspect I'm missing something silly. Any ideas?

Thanks,

Arpad

David Turner

unread,
May 27, 2011, 6:30:03 PM5/27/11
to andro...@googlegroups.com
First, it is LOCAL_SHARED_LIBRARIES, not LOCAL_SHARED_LIBRARY

Second, you cannot use the system library as a prebuilt. There is no guarantee that the version distributed with the NDK will match the one on the target device.
Actually, in the future, all link-time system shared libraries provided by the NDK will be empty shell ELF libraries that will only contain definitions of empty variable or functions for the symbols exported by the corresponding system lib.

Short version: This can't work, you cannot use libjnigraphics on 2.1


--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.


Arpad Ray

unread,
May 27, 2011, 8:05:24 PM5/27/11
to andro...@googlegroups.com
I also tried LOCAL_SHARED_LIBRARIES, having seen both in action
(indeed, in the official docs), but had equally little luck with that.

I guess my inexperience with C shows - all I was missing was to
provide both the directory containing the library in LDLIBS -L and the
name of the library in LDLIBS -l, e.g.:
`LOCAL_LDLIBS += -L$(PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)/
-ljnigraphics -lm -llog`

My entire reason for linking jnigraphics in this way is that it isn't
available at all in platforms prior to 2.2.

This works fine for me on a 2.1 device. So if, as it seems,
libjnigraphics has no external dependencies requiring a later platform
version, why should it be forcibly limited to those versions?

Given that ~25% of android users are still using 2.1, is it sensible
to preclude these features from them?

Regards,

Arpad

David Turner

unread,
May 27, 2011, 8:21:22 PM5/27/11
to andro...@googlegroups.com
On Fri, May 27, 2011 at 5:05 PM, Arpad Ray <arra...@gmail.com> wrote:
I also tried LOCAL_SHARED_LIBRARIES, having seen both in action
(indeed, in the official docs), but had equally little luck with that.

I guess my inexperience with C shows - all I was missing was to
provide both the directory containing the library in LDLIBS -L and the
name of the library in LDLIBS -l, e.g.:
`LOCAL_LDLIBS += -L$(PROJECT_PATH)/libs/$(TARGET_ARCH_ABI)/
-ljnigraphics -lm -llog`


You don't have to use -L and -l, just putting the path to the library file should be enough, i.e.:

LOCAL_LDLIBS += /path/to/libfoo.so


 
My entire reason for linking jnigraphics in this way is that it isn't
available at all in platforms prior to 2.2.

This works fine for me on a 2.1 device. So if, as it seems,
libjnigraphics has no external dependencies requiring a later platform
version, why should it be forcibly limited to those versions?

There is no guarantee that it will work on all 2.1 devices at all. You're just lucky.
If it works for you good, but be prepared to eventually deal with user complaints once your app is on Market.

Arpad Ray

unread,
May 27, 2011, 8:31:20 PM5/27/11
to andro...@googlegroups.com
On Sat, May 28, 2011 at 1:21 AM, David Turner <di...@android.com> wrote:
> There is no guarantee that it will work on all 2.1 devices at all. You're
> just lucky.
> If it works for you good, but be prepared to eventually deal with user
> complaints once your app is on Market.


Could you elaborate on this? I'm genuinely curious, how this approach
might not work for other users on the targeted platform.

Thanks,

Arpad

David Turner

unread,
May 27, 2011, 8:34:29 PM5/27/11
to andro...@googlegroups.com
libjnigraphics.so is a tiny wrapper around other system libraries that are not exposed by the NDK.
These libraries can be modified liberally by OEMs. More generally, a minor platform update (OTA or upgrade)
can also change them in ways that break libjnigraphics.so.

When I say OEM, I really mean anyone making a custom ROM too.

If you use the system's libjnigraphics.so, you now that if an OTA modifies the system libraries it uses, libjnigraphics.so will be updated by the OTA as well so everything keeps on going.

Arpad Ray

unread,
May 27, 2011, 8:35:37 PM5/27/11
to andro...@googlegroups.com
On Sat, May 28, 2011 at 1:21 AM, David Turner <di...@android.com> wrote:
> You don't have to use -L and -l, just putting the path to the library file
> should be enough, i.e.:
> LOCAL_LDLIBS += /path/to/libfoo.so

This does indeed work, thanks.

Regards,

Arpad

Arpad Ray

unread,
May 27, 2011, 8:51:35 PM5/27/11
to andro...@googlegroups.com
On Sat, May 28, 2011 at 1:34 AM, David Turner <di...@android.com> wrote:
> libjnigraphics.so is a tiny wrapper around other system libraries that are
> not exposed by the NDK.
> These libraries can be modified liberally by OEMs. More generally, a minor
> platform update (OTA or upgrade)
> can also change them in ways that break libjnigraphics.so.
> When I say OEM, I really mean anyone making a custom ROM too.
> If you use the system's libjnigraphics.so, you now that if an OTA modifies
> the system libraries it uses, libjnigraphics.so will be updated by the OTA
> as well so everything keeps on going.


That makes sense, and I appreciate the clarification, thanks.

What assurance is there that this won't be broken for the 2.2 platform?

Also, how would you recommend tackling high performance graphics then?

Regards,

Arpad

David Turner

unread,
May 27, 2011, 8:56:20 PM5/27/11
to andro...@googlegroups.com
On Fri, May 27, 2011 at 5:51 PM, Arpad Ray <arra...@gmail.com> wrote:

That makes sense, and I appreciate the clarification, thanks.

What assurance is there that this won't be broken for the 2.2 platform?

Well, the fact that we expose it through the NDK guarantees that the thing will work for the next 10 years.
This is why we're reluctant to expose many parts of the platform (given how things change with rage between releases).
 
Also, how would you recommend tackling high performance graphics then?

Simply not possible on Eclair. Your trick is probably the best way to do it, but isn't 100% safe.
 
Regards,

Arpad Ray

unread,
May 27, 2011, 9:09:23 PM5/27/11
to andro...@googlegroups.com
On Sat, May 28, 2011 at 1:56 AM, David Turner <di...@android.com> wrote:
> Well, the fact that we expose it through the NDK guarantees that the thing
> will work for the next 10 years.
> This is why we're reluctant to expose many parts of the platform (given how
> things change with rage between releases).
>>
>> Also, how would you recommend tackling high performance graphics then?
>>
> Simply not possible on Eclair. Your trick is probably the best way to do it,
> but isn't 100% safe.

Ok, thanks a lot for your help, I feel at least 50% less clueless now ;)

Cheers,

Arpad

Fredrik

unread,
May 27, 2011, 5:19:59 PM5/27/11
to android-ndk
libjnigraphics is only available from android 2.2 onwards (check out
$NDK/docs/STABLE-APIS.html for API availability).

Fredrik

Stephen Williams

unread,
Jun 7, 2011, 2:48:26 PM6/7/11
to andro...@googlegroups.com
The best alternative is probably to new byte[] in Java, pass it to JNI, then pin / read/write / unpin in C/C++.  Then create a Bitmap from that byte array (a single, high-performance copy).

If Bitmap had a way to directly access its byte[] buffer, you could use that.  This is, I believe, exactly what jnigraphics does.  The reason you can link with it but it might not work is that it, I think, uses private APIs in Java via JNI to get to the internal byte[] of a Bitmap.  This will fail at runtime if the Java code doesn't have that private API.

Early Android uses direct buffers for Bitmaps while current Android uses standard Java byte arrays.

You could easily link with jnigraphics, but only use that method on 2.2 or greater systems.  Fallback to the fast byte[] copy method for older Android versions.  That should work back to 1.6.

Stephen

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.




--
--
Stephen D. Williams s...@lig.net scie...@gmail.com LinkedIn: http://sdw.st/in
V:650-450-UNIX (8649) V:866.SDW.UNIX V:703.371.9362 F:703.995.0407
AIM:sdw Skype:StephenDWilliams Resume: http://sdw.st/gres
Personal: sdw.st facebook.com/sdwlig twitter.com/scienteer
Reply all
Reply to author
Forward
0 new messages