9

I am trying to use an open source C library in my Android project. This library uses the atof() function. I know that atof() is a function defined in the standard C library (stdlib.h). Therefore, it should be implemented in standard C library on the Android NDK (bionic library).

But, when I try to load a library that contains calls to this function, I receive a runtime error:

java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1285]:    86 cannot locate 'atof'....

I am a beginner in Android development using the NDK, so maybe I just missed something like flags, compiler directives, etc.

My android.mk file is:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

LS_CPP=$(subst $(1)/,,$(wildcard $(1)/$(2)/*.c))


LOCAL_MODULE := libA

LOCAL_SHARED_LIBRARIES :=       \
                            libgmodule-2.0          \
                            libgobject-2.0          \
                            libgthread-2.0          \
                            libglib-2.0

LOCAL_SRC_FILES:= sourceFile.c



include $(BUILD_SHARED_LIBRARY
Cat
  • 66,919
  • 24
  • 133
  • 141
void
  • 1,347
  • 2
  • 13
  • 25
  • How are you building the project? Are you using a standalone toolchain, as documented inside the android-ndk-r8d/docs/STANDALONE-TOOLCHAIN.html file? – Alex Bitek Jan 29 '13 at 09:33
  • Maybe its a problem with the runtime system you are running your application on... because "the build system automatically links the C library, the Math library and the C++ support library to your native code, there is no need to list them in a LOCAL_LDLIBS line." – Alex Bitek Jan 29 '13 at 09:57
  • Sorry for late answer. LOCAL_ALLOW_UNDEFINED_SYMBOLS - turns off checking of undefined symbols,so i missed depencies on stdlib.h(atof) in another files. It my fault. I did mistake ignoring this flag. Copy&Paste is true evil. – void Jan 30 '13 at 20:37
  • @void: are you suggesting not to use `LOCAL_ALLOW_UNDEFINED_SYMBOLS`? – dd619 Nov 14 '13 at 12:49

2 Answers2

6

Google have moved some of the C standard library functions like atof() from being inline functions in header files to normal functions. The latest NDKs will default to building a .so that is only compatible with the latest Android devices that have the atof() function in the device's standard C library (libc.so). This means if you run a library on an older device that has an older version of the C library, you will get an error loading the dll as the expected atof() function will not exist.

Have you tried setting this in your Application.mk:

APP_PLATFORM := android-9

This will cause the ndk compiler to build code compatible with older Android versions.

You can also try downgrading your NDK installation to version 10b (this version predates the change where atof was moved from inline to part of libc so avoids the problem entirely).

JosephH
  • 37,173
  • 19
  • 130
  • 154
1

From stdlib.h in the Android source;

static __inline__ double atof(const char *nptr)
{
    return (strtod(nptr, NULL));
}

atof is in other words not a library function, it's an inline function that calls strtod.

If you need to call through loading a library, just use strtod instead.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • This would suggest that the library object being loaded was not compiled with the NDK, or at least not properly compiled against the NDK headers with it. Though I'm a bit surprised that if it was built with another toolchain it even got so far as to fail on a specific function rather than refusing to even try to load at all. – Chris Stratton Jan 28 '13 at 21:33
  • @ChrisStratton Surprises me too, NDKs earlier than r5 [only had a declaration, no implementation](http://code.google.com/p/android/issues/detail?id=12611) but I suspect the NDK used is not _that_ old. – Joachim Isaksson Jan 28 '13 at 21:38
  • i am using ndk r8c. i just downloaded it and using ndk-build -C "project path " without any flags and modifiers..what i did miss? – void Jan 28 '13 at 21:39
  • @void - are you building *everything* from source, or did you download prebuilt .so libraries? It would probably be a good idea to name the open source library, or take the issue up with its maintainers. – Chris Stratton Jan 28 '13 at 21:42
  • It's possible the library has a bad build setup that's using a host include (ie, for your PC) rather than the android includes for part of the build process. This could happen for example if someone at some point ran a configure script in a non-cross-compile configuration. – Chris Stratton Jan 28 '13 at 21:47
  • @Chris Stratton,ndk contains .so files. But i don't know whether ndk build uses that prebuild files or compile from source every time..how check this ? – void Jan 28 '13 at 21:48
  • @Chris Stratton "This could happen for example if someone at some point ran a configure script in a non-cross-compile configuration. " Could you explain this mo detaily? – void Jan 28 '13 at 21:50
  • @void Just double checked all references to `atof` in the NDK, they're all inline, so something in the third party library has to use its own definition (or use the prebuilt's). If it's compiled against the stdlib.h in the NDK, it should not attempt reference that symbol from a library. – Joachim Isaksson Jan 28 '13 at 21:50
  • @void - a lot of open source projects use configure scripts which attempt to learn about the environment of your computer when setting up the build. This typically works poorly when cross compiling to run on a different system, and can be disastrous when building for android. A sometimes shortcut is to say "well, android is sort of linux, let it configure for linux as a starting point and then I'll manually change what I need to to get it to build for android" - but android has a custom embedded C library, with differences from the C library on a desktop linux or even other embedded linuxes. – Chris Stratton Jan 28 '13 at 21:55
  • Sorry for late answer. LOCAL_ALLOW_UNDEFINED_SYMBOLS - turns off checking of undefined symbols,so i missed depencies on stdlib.h(atof) in another files. It my fault. I did mistake ignoring this flag. Copy&Paste is true evil. – void Jan 30 '13 at 20:37
  • sorry if I am asking a dumb question, but how is this linking error solved? I'm running into the same issue. I rebuilt ffmpeg for my app and in it's codebase, atof is referenced apparently. However, I don't want to modify it's source just to change all atof instances to call the atod. I just don't know what the solution is. I built a standalone toolchain for the ndk. I think the issue is that I also pass -std=c++11 as one of my flags. I'm at a loss. Please help – Michael Nguyen Aug 12 '14 at 01:43
  • @JoachimIsaksson I have got a similar problem please can you help me with this problem? http://stackoverflow.com/questions/38374399/unsatisfied-link-error-dlopen-failed-cannot-locate-symbol-atof – anup Jul 14 '16 at 12:39