How to use unordered_map in Android? - android

I am trying to use a hash_map, defined in the Android NDK, but I get a "deprecation warning":
ndk/sources/cxx-stl/gnu-libstdc++/4.6/include/ext/../backward/backward_warning.h:33:2:
error: #warning This file includes at least one deprecated or antiquated header which may
be removed without further notice at a future date. Please use a non-deprecated interface
with equivalent functionality instead. For a listing of replacement headers and
interfaces, consult the file backward_warning.h. To disable this warning use -Wno-
deprecated. [-Werror=cpp]
And since "unordered_map" is present in gnu-libstdc++/4.6/include/ and also in gnu-libstdc++/4.6/include/tr1/, I believe that there is a way to use it.
The point is that I cannot find it. Which of the following is the right one (if any):
#include <tr1/unordered_map.h>
#include <unordered_map>
And then, how to use it? __gnu_cxx::unordered_map is not recognized... and I don't know how to find this information.

In case you don't want/need C++11 support, you can use the one from the STLPort using:
// Here we are referencing the stlport one:
#include <unordered_map>
...
std::tr1::unordered_map<int, int> test;
That's because STLPort defines unordered_map inside tr1 namespace, but the STLPort header is not inside any /tr1/ folder.

I eventually found a way by adding C++11 support in my Android project. Pretty easy when we know it, but I took some time to figure it out. Neither STLPort nor Boost were needed. Once C++11 was integrated, I could use "unordered_map" as follows:
#include <unordered_map>
...
std::unordered_map<int, int> test;
I created a new question to explain how to enable C++11 support in Android here.

Related

Pass JNIEnv or Context from Java to Go

I've successfully written a go mobile library and used it from an Android Java app.
I've also successfully called a c function from JNI. This one has the JNIEnv pointer.
I'd like to pass the context/JNIEnv from Java to Go.
Here's where it seems to get complicated:
Go Mobile does not seem to use JNIEnv at all.
LoadJNI.java does have a context object and claims to pass it to the Go side. But there it isn't visible.
I've been able to include jni.h using the "C" directive
I can transfer the JNIEnv from JNI/C or store it there as a global variable but that's an ugly kludge.
https://github.com/golang/go/issues/16876 talks about a proposal to do reverse binding but it's unclear what the status is.
https://godoc.org/golang.org/x/mobile/cmd/gobind also talks about it but the following code snippet
import "Java/java/lang/System"
t := System.CurrentTimeMillis()
returns
cannot find package "Java/java/lang/System" in any of:
/usr/local/go/src/Java/java/lang/System (from $GOROOT)
/Users/----/go/src/Java/java/lang/System (from $GOPATH)
In C I solved it with a compiler directive: #cgo CFLAGS: -I...
But I'm not sure how to do it for Java
In short, I'm now stuck and would appreciate help. Ideally, I'd just like to pass the object as a parameter, if possible. However, I'd settle for any reverse binding to call Java from Go.
I hate to answer my own question, but I'd hate someone to go through this as well too. I'll update this answer as I go along.
Basic Setup
Edit build.gradle and add GOPATH and GO to gobind (additions in bold):
gobind {
pkg = ".../reverse/reverse"
GOPATH = "/Users/johndoe/go"
GO = "/usr/local/go/bin"
}
How to develop
Start from the reverse example. Get it to compile and run.
Make one modification and recompile.
Missing gobind
It turns out the installation process neglected to build gobind. Run go install golang.org/x/mobile/cmd/gobind
I'm Stuck
Trying to modify the reverse project to do anything other than what it's already doing is failing. Even stuff like passing an object and calling toString will fail.
More to come...

Making sense of symbol table entry (when header function is not present)

I have a JNI function in a C++ library.
When I create the library using cmake (but forget to put function declaration) in the header file, the library is created successfully.
When I look for function name in library symbol table I get following output
nm libuserlibrary.so | grep printxx
00506e60 T _Z60Java_com_example_user_myapplication_userlibrary_printxxP7JNIEnv_P8_jobject
But when I give function declaration in the header file, I get following output
nm libuserlibrary.so | grep printxx
00506e50 T Java_com_example_user_myapplication_userlibrary_printxx
Why is there this difference between these two symbol table entries? What is the purpose of _Z60 and P7JNIEnv_P8_jobject around the function name?
I also noticed that in the first case, I cannot call the JNI funciton from Android java code (it says unsatisfied-linker-error, implementation not found).
C++ allows function overloads and namespaces like Java does. So, it annotated the function name with parameter information so the linker can bind to the correct overload.
JNI was designed for C which does not allow function overloads or namespaces. So it invented it's own annotation system and provides the javah tool to help you use it. The header can be used in C++ too. C++ was designed to allow some functions to be called as if they written in C. The header has code that indicates that to the compiler. So, put it all together and you can write Java-callable functions in C++.

SQLite Android NDK add custom functions

I have managed to get SQLite setup using the NDK, but I can't manage to get custom functions to work which was the whole reason for implementing SQLite using the NDK.
I used this library to get the same SQLite files. It also contains an extension file called extensionfunctions.c which adds in string and mathematical functions for SQLite.
From what I can see, the SQLite implementation appears to be working correctly, but I cannot call any of the custom functions.
I've little to no knowledge of C/C++, so any help would be great. Do I have to compile the extensionfunctions.c file independently, and then add in the SO file with the libsqliteX.so file? Or do I have to make a call in the android_database_SQLiteCommon.cpp to load in the other extension? I've no idea how this works.
Edit
The file extensionfunctions.c is included in sqlite3secure.c which is in the Android.mk file under LOCAL_SRC_FILES. I assume that means the file is being used correctly, but none of the custom functions are accessible.
Edit 2
// To enable the extension functions define SQLITE_ENABLE_EXTFUNC on compiling this module
#ifdef SQLITE_ENABLE_EXTFUNC
#define sqlite3_open sqlite3_open_internal
#define sqlite3_open16 sqlite3_open16_internal
#define sqlite3_open_v2 sqlite3_open_v2_internal
#endif
#include "sqlite3.c"
#ifdef SQLITE_ENABLE_EXTFUNC
#undef sqlite3_open
#undef sqlite3_open16
#undef sqlite3_open_v2
#endif
I found the above code with the comment and I added in the line below but it appears as though nothing has changed.
#define SQLITE_ENABLE_EXTFUNC
Do I have to do anything to get the app to refresh it's version of the sqlite3 files or could that be a problem? My C skills are poor so I assume what I did is what the comment has referring to?

Can't put math.h in a namespace

I'm doing some cross platform development, and I ran across another weird problem..
namespace Math
{
#include <math.h>
}
This is what I am trying to do. It works fine on iOS, but on Android everything inside math.h is not a member of Math when I try to compile it. After some trial an error I found out that the ndk doesn't put the stuff in math.h in the namespace Math, as the functions do exist without the Math:: prefix. The big problem is that some functions in math.h clash with my own convenience functions. How can I fix this?
You really shouldn't try to put any system headers into a different namespace. The solution, as painful as it may be at this point in development, is to put all of your code into its own namespace.
What about <cmath>? it puts everything in std:: (in C++11).
Don't put your convenience functions in the global namespace.
Don't try to wrap math.h in a namespace.
There, all’OK now.
Cheers & hth.,
Probably something else includes math.h earlier in the preprocessor "pipeline". C includes check whether the sane include has been included earlier. In this case, the check #ifndef MATH_H resulted in excluding the whole file. Try placing your include with the namespace at the beginning of your .c files.

What's the difference in GCC between -std=gnu++0x and -std=c++0x and which one should be used?

I'm having troubles with <stdint.h> when using -std=c++0x in GCC 4.4.3 (for Android):
// using -std=c++0x
#include <stdint.h>
uint64_t value; // error: 'uint64_t' does not name a type
But using -std=gnu++0x works:
// using -std=gnu++0x
#include <stdint.h>
uint64_t value; // OK
Is <stdint.h> incompatible with C++0x?
So far as I can tell, I think this could be argued an implementation bug (or actually, since C++0x isn't published, not a bug per se but an incomplete implementation of the current state of the upcoming standard).
Here's why, referring to n3225 for the expected behavior of -std=c++0x:
D.7 says
Every C header, each of which has a
name of the form name.h, behaves as if
each name placed in the standard
library namespace by the corresponding
cname header is placed within the
global namespace scope
OK, so far so easy. What does <cstdint> place in the standard library namespace?
18.4.1:
typedef unsigned integer type uint64_t; // optional
How optional? 18.4.1/2:
The header defines all functions,
types, and macros the same as 7.18 in
the C standard
Drat. What does the C standard say? Taking out n1256, 7.18.1.1/3:
These types are optional. However,
if an implementation provides integer
types with widths of 8, 16, 32, or 64
bits, no padding bits, and (for the
signed types) that have a
two's complement representation, it
shall define the corresponding typedef
names
But hang on, surely on Android with -std=c++0x GCC does provide a 64 bit unsigned type with no padding bits: unsigned long long. So <cstdint> is required to provide std::uint64_t and hence stdint.h is required to provide uint64_t in the global namespace.
Go on, someone tell me why I'm wrong :-) One possibility is that C++0x refers to "ISO/IEC 9899:1999 Programming languages — C" without specifying a version. Can it really be that (a) 7.18.1.1/3 was added in one of the TCs, and also (b) C++0x intends to reference the original standard as of 1999, not the amendments since then? I doubt either of these is the case, but I don't have the original C99 on hand to check (a) and I'm not even sure how to check (b).
Edit: oh, as for which one should be used -std=c++0x isn't really a strict standards-compliant mode yet, since there isn't a strict standard yet. And even if there was a standard, gcc 4.4.3 certainly isn't a finished implementation of it. So I see no great need to use it if -std=gnu++0x is actually more complete, at least in this respect for your combination of gcc version and platform.
However, gnu++0x will enable other GNU extensions, that you might not want your code to use. If you're aiming to write portable C++0x, then eventually you'd want to switch to -std=c++0x. But I don't think GCC 4.4 or any other C++0x implementation-in-progress is complete enough yet for it to be practical to write code from the (draft) standard, such that you could say with a straight face "I'm programming C++0x, and it's only 2011!". So I'd say, use whichever one works, and understand that whichever one you use now, you'll probably be switching to -std=c++11 eventually anyway.

Categories

Resources