In android ndk c++ in visual studio, I'm trying to use memmove.
The compiler throws:
error : 'memmove' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation
I include string.h so, I don't get what I am missing here...
I inspected the string.h and found that the definition of memmove in string.h in the ndk is inside a preprocessor block
#if defined(__BIONIC_FORTIFY)
And is undefined.
I don't know what is this preprocessor and why it is preventing the memmove from being defined.
What is this __BIONIC_FORTIFY thing? is it safe to define?
Is there a problem using memmove in android?
My research : this preprocessor is defined by
#define _FORTIFY_SOURCE
but adding this to my build does not get rid of the error.
Related
I'm trying to use AndroidJniBitmapOperations library.
But I'm a Junior Dev, with no knowledge in the NDK, JNI world.
I succeed to resolve a few errors like 'UnsatisfiedLinkError', but Now I'm getting a new one when I trying to build:
error: undefined reference to 'AndroidBitmap_unlockPixels'
Also I get a few errors inside the CPP file:
1."Incorrect type for parameter 'prarmeterName', which should have type 'jint'.
2."Add extern 'C'"
But I don't sure if the last 2 are important.
Help me to update this library, because its important and talked in SO several times, like: here.
The link for the library it self:
https://github.com/AndroidDeveloperLB/AndroidJniBitmapOperations
All what I have done until now is:
https://github.com/LiorA1/MyRevApp
You need to link the library that provides that API. In https://github.com/LiorA1/MyRevApp/blob/master/app/src/main/cpp/CMakeLists.txt, copy the code that you have for the logging library like so:
find_library(log-lib log)
find_library(jnigraphics-lib jnigraphics)
target_link_libraries(JniBitmapOperationsLibrary ${log-lib} ${jnigraphics-lib})
Although I think the template code is actually overly complicated here and you can simplify to just:
target_link_libraries(JniBitmapOperationsLibrary -llog -ljnigraphics)
Untested though.
As for how you can figure out which library you need to use for each Android API, I find the easiest way is to search for it on cs.android.com. For this one, I searched for AndroidBitmap_unlockPixels file:.*\.map\.txt (every NDK API is enumerated in a *.map.txt file). You can also use this page, but the code search is authoritative and makes it easier to look up an individual function rather than just "bitmap", in this case.
I am seeing a very strange failure that is very similar to the problem described in
dynamic_cast on llvm clang compiler failing: dynamic_cast returns nullptr when I am trying to downcast from base type to derived type, for an object of derived type. In my case though typeid actually shows the same dynamic type.
Below is the debug function that I use to verify run-time types. It takes a pointer of SrcType* and tries to dynamically cast it to pointer of DstType*. If conversion fails, i.e. the returned pointer is nullptr, it prints an error message. VERIFY() macro checks if condition is true:
template<typename DstType, typename SrcType>
void CheckDynamicType( SrcType *pSrcPtr )
{
VERIFY(dynamic_cast<DstType*> (pSrcPtr) != nullptr,
"Dynamic type cast failed. Src typeid: \'", typeid(*pSrcPtr).name(),
"\' Dst typeid: \'", typeid(DstType).name(), '\'');
}
And here is the output that I am getting:
Dynamic type cast failed. Src typeid: 'N8Diligent15RefCountersImplE' Dst typeid: 'N8Diligent15RefCountersImplE'
I am using clang compiler from Android ndk r16 toolchain. I am compiling with rtti flag. The same code works fine on gcc and msvc.
Another bit of information: the code also works fine if I build it with gnustl runtime (I am not sure how gnu stl works with clang, but anyway).
UPDATE
After spending few more hours looking into the issue I found out that dynamic_cast fails when it is used on the object created in another module.
From this
Using clang++, -fvisibility=hidden, and typeinfo, and type-erasure and this posts it looks like dynamic_cast should work if the class is labeled with __attribute__((visibility("default"))) so that typeid structures from two modules will be merged. This, however does not help either and I am still seeing the issue.
If you’re using the stock system compiler there’s a near 0 chance dynamic_cast of the compiler isn’t working. This is tested and used extensively in everything from system software up.
I am building an Android app that loads in 2 native shared libraries at runtime: 1 that was built with an unresolved symbol in it and the other which resolves and defines that symbol. In Java, I load the shared library that defines the symbol first, then load the library that has the symbol declared as unresolved, and at this point, the runtime fails with:
"Cannot load library: reloc_library[]: 33 cannot locate 'someMethod'
So here's the one unique difference. The shared library with the undefined symbol obviously doesn't know about the shared library with the definition for the symbol in it.
I just assumed that if I loaded the library with the definition of the method first that when I loaded the 2nd library that called the method, it would be able to find it. Am I wrong on that? It seems in my case, an explicit dependency HAS to be compiled in between the two native libs, which means (I think) making .so's with unresolved symbols is useless.
I have searched vigorously for a similar issue with no luck. I think my problem is due to an architectural limitation, and I am considering approaching it a couple of other ways, but I would like to know if it can be fixed simply.
To be sure it wasn't some complexity of the library itself, I created two very simple C files:
fcn_defined.c:
int someMethod()
{
return 1;
}
fcn_undefined.c:
extern int someMethod();
int someOtherMethod()
{
someMethod();
}
Then build two shared objects where the fcn_undefined.c code creates a .so with someMethod still undefined and fcn_defined.c builds a .so with someMethod defined:
gcc -o libfcn_undefined.so fcn_undefined.c -shared -Wl,--export-dynamic
gcc -o libfcn_defined.so fcn_defined.c -shared -Wl,--export-dynamic
Doing a nm on these produces:
libfcn_undefined.so:
0001f08 d _DYNAMIC
00001fe8 d _GLOBAL_OFFSET_TABLE_
00002004 A __bss_start
U __cxa_atexit
U __cxa_finalize
00002000 d __dso_handle
00000290 t __on_dlclose
00002004 A _edata
00002004 A _end
000002a0 t atexit
000002b4 T someOtherMethod
U someMethod
and libfcn_defined.so:
00001f0c d _DYNAMIC
00001fec d _GLOBAL_OFFSET_TABLE_
00002004 A __bss_start
U __cxa_atexit
U __cxa_finalize
00002000 d __dso_handle
0000025c t __on_dlclose
00002004 A _edata
00002004 A _end
0000026c t atexit
00000280 T someMethod
So you can see someMethod() is defined in libfcn_defined.so (and it appears in the read elf dynsym section) and is undefined in the other lib.
If anyone is interested in the readelf output, I can add that as well.
In the Java side, I have a simple button in the emulator that I click, and it creates a class with the following in it:
static
{
System.loadLibrary("fcn_defined");
System.loadLibrary("fcn_undefined");
}
Just out of curiosity, I added a "-lfcn_defined" to the fcn_undefined compile line, and compared the nm and readelf outputs. the only difference in nm was that the "T someOtherMethod" started a few bytes further out and the readelf difference was the "NEEDED" line for fcn_defined. That's pretty much about what I expected. And it doesn't crash like this.
That's pretty much the full explanation. I did find some details about how Android forces you to load your libraries in reverse dependency order in Java, because it has (rather it had, has been fixed in API 18) no reference to your app's lib path in the LD_LIBRARY_PATH envvar. Unfortunately, I am requiring a minimum API lvl 10 to be able to use my app because of the market penetration, and secondly I tried API 19 anyway, and it still fails.
If I had to guess, I believe Android just doesn't support finding a symbol if you haven't explicitly told it to look at library X for the symbol. In other words, because I didn't build the library fcn_undefined with an explicit dependency on libfcn_defined.so, Android can't resolve it. Does anyone know if this is a bug or by design? Is this normal? It seems like you wouldn't have the option to create a .so with unresolved symbols if this was the case, and even funnier is that the Android NDK toolchain I'm using to build this has this feature on by default when you use ld (it doesn't complain about unresolved), and I tried turning the feature off but didn't seem to do anything, no warnings or errors generating the library.
So you may ask why I don't just compile the fcn_undefined library with a dependency on the fcn_defined library. Well that gets into a much bigger architectural discussion. The code I'm working with (fcn_undefined.c in this example) is a python extension built with a cross compiled python toolchain for ARM, and I'm calling this library from an NDK library, so now the NDK library depends on the python module which has an unresolved method in Python, which is defined in a static lib. Linking the static lib into the NDK shared lib means that I can't load the native shared libs in the correct order in Java (due to the issue mentioned previously that they fixed in API 18). I'm trying to work with the existing system since a team of others use it, and it is used to build for many platforms. sigh I clearly have other things to figure out, but I was hoping to nail the one above down at least.
The behavior you so beautifully demonstrated is by design (or lack of, if you will). You are right in part, the crazy_linker does resolve some of such issues (but not all of them). There is an easy but ugly workaround. Build a dummy libfcn_defined.so which only has T someMethod in its nm. Use it to link libfnc_undefined.so, using LD_LIBS. NDK will show a warning, but that's OK. LAoad the real libfcn_defined.so in your Java.
By Unix/ELF design, you need a NEEDED entry in libfnc_undefined.so that lists libfnc_defines.so as a dependency for the dynamic linker to look into it for missing symbols.
I.e. you should ensure that -lfcn_defined (or /path/to/libfcn_defined.so) appears in the link command that generated libfcn_undefined.so.
If you use ndk-build to generate both libraries, just list libfcn_defined.so as a LOCAL_STATIC_LIBRARIES or LOCAL_SHARED_LIBRARIES entry for libfcn_undefined.so.
If you use another build system, adapt accordingly.
I'm trying to get the Eventinjector project from pocketmagic.net found here.
This means working with a precoded jni library writen in C. My problem is that I get some build errors when I try to compile the native code. The error log is long and I believe all errors are the same, therefore I'll only post part of it.
jni/EventInjector.h:718:9: error: (near initialization for 'mt_tool_labels[0].value')
jni/EventInjector.h:719:9: error: 'MT_TOOL_PEN' undeclared here (not in a function)
jni/EventInjector.h:719:9: error: initializer element is not constant
jni/EventInjector.h:719:9: error: (near initialization for 'mt_tool_labels[1].value')
jni/EventInjector.h:720:9: error: 'MT_TOOL_MAX' undeclared here (not in a function)
jni/EventInjector.h:720:9: error: initializer element is not constant
jni/EventInjector.h:720:9: error: (near initialization for 'mt_tool_labels[2].value')
jni/EventInjector.c: In function 'debug':
jni/EventInjector.c:82:2: error: format not a string literal and no format arguments [- Werror=format-security]
cc1.exe: some warnings being treated as errors
make: *** [obj/local/armeabi/objs/EventInjector/EventInjector.o] Error 1
Going throught the comments under the blogpost I discovered that "Alessandro" had the same problem but had found a solution. (post 51) " I had the same issue and imported my own input.h version containing all the missing declarations."
This is the part of the .c file that generates most of the errors:
static struct label key_labels[] = {
LABEL(KEY_RESERVED),
LABEL(KEY_ESC),
LABEL(KEY_1),
LABEL(KEY_2),
LABEL(KEY_3),
LABEL(KEY_4),
LABEL(KEY_5),
LABEL(KEY_6),
LABEL(KEY_7),
LABEL(KEY_8),
LABEL(KEY_9),
LABEL(KEY_0),
LABEL(KEY_MINUS),
LABEL(KEY_EQUAL),
LABEL(KEY_BACKSPACE),
...
I have no experience in C, and don't know what he means. So my question is: how do I do this?
I have succesfully compiled other JNI libs, using NDK v9 and cygwin, so there should not be a problem with my settings and enviroment.
I had the same issue and imported my own input.h version containing all the missing declarations.
You can do same thing and replace your input.h (you can search for input.h with those undefine identifiers in linux kernel sources), but easier way is to remove lines containing undefined identifiers from EventInjector.h. Just comment all lines that highlighted red in eclipse, and it should work.
I am porting to SDL2 and the Android platform a C++ game that uses SDL 1.2. Everything went well so far except for one thing: when I try to access the fields of SDL_Window, the compiler tells me
error: invalid use of incomplete type 'SDL_Window {aka struct SDL_Window}'
I think my installation of SDL may be faulty. I have compiled SDL 2.0.0 from the source found on libsdl.org using the folloing command:
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_PLATFORM=android-18
Then, I have copied the freshly built libSDL2.so into $ANDROID_TOOLCHAIN/sysroot/usr/lib and the files in the include/ directory in $ANDROID_TOOLCHAIN/sysroot/usr/include/SDL. These files are given to CMake and referenced by the game's code. I managed to convert every SDL calls and now I am stuck with this SDL_Window problem.
I did a quick search in SDL's source code and found that SDL.h includes SDL_video.h which contains a typedef SDL_Window on struct SDL_Window. Then I searched for this struct and did not find anything except in the original source archive, in a file named src/video/SDL_sysvideo.h. Since it is not a file of the API, I doubt I have to include it in my code.
So, how to find a definition of SDL_Window in SDL2, for Android (if this is relevant)?
It appears that the problem is a lack of knowledge of SDL 2's API. Let's remember that one does not access the fields of struct SDL_Window: there are functions to get the size and the flags of the window, such as SDL_GetWindowFlags and SDL_GetWindowSize.
So the problem is absolutely not related to the installation of the SDL or to Android builds. Sorry for the waste of time, people of the Web.
I would expect that you are expected to only deal in pointers to SDL_Window objects, and not actually put a full SDL_Window object on the stack.