Android NDK seekg broken? - android

I am using the following code:
fileIn.seekg(12,std::ios::beg);
uint16_t data;
fileIn>>data;
LOG_D("app","file data=%u",data);
But what actually happens is it logs the value of offset I pass in seekg like in the given case it Logs
file data=12
If i use
fileIn.seekg(8,std::ios::beg);
then it prints "file data=8"
in general it prints
file data=x for fileIn.seekg(x,std::ios::beg);
its very mysterious to me ! I am using android ndk r10d c++ with eclipse for ARM thumb target

Have you checked that anything was actually read from the stream? I'm guessing you're just printing out garbage data.

Related

What's the simplest way to see logging from a Qt app on Android in adb logcat output?

NB I am not a QtCreator user. I build android apps in build scripts with qmake, make and androiddeployqt, and deploy them to the device with adb install.
I'd like to be able to see the output of qDebug, qInfo etc, and also any qml conole.log output and any other chatter from the QML engine, in abd logcat output. But in a vanilla build of a Qt app for Android, any such messages just seem to be blackholed (or at least I have no idea where they're going).
I have had some success by the combination of:
Redirecting logging to stderr using qInstallMessageHandler (as shown here).
Redirecting stderr to Android logging using the code here. (Update: subsequently discovered this approach is rather unsatisfactory as it relies on another thread listening on a pipe, and crashing apps can lose the logging immediately preceeding the crash).
But this all seems a bit clunky and and overcomplicated. Surely there's a better and simpler way? (For example, with Qt on Windows you can simply build with CONFIG += console to get a console window with logging displayed, but that option is Windows specific).
Qt versions from 5.7 onwards of interest.
Googling this output redirection issue turns up quite a lot of mention of adb shell setprop log.redirect-stdio true, however so far as I can tell it has no effect on Qt apps' stout/stderr.
Actually, combining aspects of the two solutions linked in the question at least reduces it to one function:
const char*const applicationName="myapp";
#ifdef ANDROIDQUIRKS // Set in my myapp.pro file for android builds
#include <android/log.h>
void myMessageHandler(
QtMsgType type,
const QMessageLogContext& context,
const QString& msg
) {
QString report=msg;
if (context.file && !QString(context.file).isEmpty()) {
report+=" in file ";
report+=QString(context.file);
report+=" line ";
report+=QString::number(context.line);
}
if (context.function && !QString(context.function).isEmpty()) {
report+=+" function ";
report+=QString(context.function);
}
const char*const local=report.toLocal8Bit().constData();
switch (type) {
case QtDebugMsg:
__android_log_write(ANDROID_LOG_DEBUG,applicationName,local);
break;
case QtInfoMsg:
__android_log_write(ANDROID_LOG_INFO,applicationName,local);
break;
case QtWarningMsg:
__android_log_write(ANDROID_LOG_WARN,applicationName,local);
break;
case QtCriticalMsg:
__android_log_write(ANDROID_LOG_ERROR,applicationName,local);
break;
case QtFatalMsg:
default:
__android_log_write(ANDROID_LOG_FATAL,applicationName,local);
abort();
}
}
#endif
...
int main(int argc,char* argv[]) {
QGuiApplication app(argc,argv);
#ifdef ANDROIDQUIRKS
qInstallMessageHandler(myMessageHandler);
#endif
app.setApplicationName(applicationName);
...
This gets things like qInfo() << messages from C++ and console.log messages from QML. What it doesn't get is stdout/stderr output, but I can live with that for new code which can use Qt logging throughout.
In logcat, the QML code Component.onCompleted: console.log("QML completed") results in
08-02 12:27:53.378 1199 1220 D myapp : QML completed in file qrc:///main.qml line 7 function onCompleted
and in C++ the code qInfo() << "QQuickViewer setup completed"; produces
08-02 12:27:53.562 1199 1220 I myapp : QQuickViewer setup completed
Installing the message handler even before QGuiApplication is instantiated seems to work equally well, but it doesn't generate any additional output (I note Qt on iOS spews all sorts of stuff on startup to the xcode console e.g a performance warning linking to https://wiki.qt.io/V4 and wondered if Android did the same; but if it's emitting anything it must be before my handler is installed).

armeabi-v7a compiling error for cpp file

I am using getline function and compiling using ndk but i am getting error :
'getline' was not declared in this scope
is this error due to limitations of armeabi-v7a or due to glib?How can it be resolved for the same function.
I have already #define _GNU_SOURCE before <stdio.h>
In general, when you encounter such an error, you go to your NDK directory and user either Midnight Commander (Linux) or Far Manager (Windows, Linux+Wine) to search the files (file mask: *.h) for your function, getline in this case. You will get a screenful of search results, and it's up to you to #include the right file.
Once in a while your function will not be found; in this case you search the 'net for a place where you can borrow the source.
Sometimes the function in the code being ported has just no meaning, e.g. if the function reads a line from stdin but the program going to invoke it is not a command-line utility, there is a problem.
Most likely, the source that you port #define-s switches for Linux, Mac (Darwin) and Windows, you have to choose the right configuration to derive the Android configuration from (and probably the Mac one will be the best).

How to implement mbtowc for android? (or, ideally, how not to?)

I am attempting to build an Android app that makes use of boost serialization. I have built the library against NDK r8d using arm 4.7's g++. When I go to compile my native code into a library using ndk-build, however, I get "undefined reference to 'mbtowc'" and "undefined reference to 'wctomb'" when the compiler attempts to link some code from Archive headers in boost.
I cannot seem to get a clear answer as to whether the NDK supports these functions.
Although it implements the functions, the CrystaX NDK is not an option as it has known crashes when using it with Boost, according to the Boost mailing list.
So, if the NDK does implement these functions somehow, why is NDK-build unable to link against them? I can find reference to them in cstdlib within the NDK, and I believe there may be a flag I need to set, but I'm not sure how or where to do so.
If there is no implementation of them, does anyone have any advice on how I can write them myself? I know roughly what mbtowc and its complement are supposed to do, but without much experience writing low-level C, and without much knowledge of Android / ARM architecture, I could really use some advice on doing so.
#ifdef ANDROID
int wctomb(char *s, wchar_t wc) { return wcrtomb(s,wc,NULL); }
int mbtowc(wchar_t *pwc, const char *s, size_t n) { return mbrtowc(pwc, s, n, NULL); }
#endif
Findings! Yes, boost has options to build it without requiring wchar support by adding preprocessor definitions to the boost build scripts. Boost still crashes when built using them at the line of code where I attempt to serialize an object to file. (the crash is a generic segfault at 0x00000000, and I was unable to gain any useful information).
So, I haven't bothered writing wctomb or its inverse. I shouldn't need to, is the answer to my question, although in the end the answer to the question doesn't matter.
To further clarify: don't bother doing what I've been trying to do. If you have been using Boost's serialization library and want your code to run on android ndk r8d or earlier, just give up. Write a serializer yourself, because there is no useful information to be found on how to make Serialization work. Hopefully a future release of the ndk fixes this problem, but for now I have no choice but to just rewrite everything.
I had the same problem. I was creating an android port for code that uses boost::serialization.
My code failed to compile because of missing implementation of mbtowc / wctomb (mb: multi-byte (char), wc: (wide-char)'
Implementation of these functions will probably be tricky cause as far as I know the wide-char for android is a single byte char instead of a true wide character..
However when I compiled boost with -DBOOST_NO_STD_WSTRING the link errors disappeared and I could use boost::archive::text_iarchive & boost::archive::text_oarchive on android.
I am now serializing STL containers of numerics and std::strings without a problem.
I compiled boost for android following the advice on this link: http://www.codexperiments.com/android/2011/05/tips-tricks-building-boost-with-ndk-r5/
I am using boost-1.55_0 and NDK r9c.
I added the following <compileflags>-DBOOST_NO_STD_WSTRING to the build command so it would build serialization library without wide character support.

Porting cURL to Android with NDK

Good day to you. I'm currently struggling at porting cURL onto my Android app - many subjects do talk about this, but no single post or tutorial or whatever does clearly say what to do or just don't work at all.
I do own every single tool needed, have the latest version of cURL (7.28.0). I tried to do it using cross-compiling and a toolchain (part that work good) but when I'm trying to configure the curl-7.28.0, the ./configure --host=arm-linux-androideabi (or any argument that is pass) return the following error :
./configure: line 20: $'\r' : unknown command
./configure: line 35: Syntax error near unexpected token « newline »
'/configure: line 35: ` ;;
If someone had already gone through this and does have the memories of the steps he followed or knows what I do wrong, it would be a blessing if you could help my poor soul !
Thanks in advance.
Note : I'm using Cygwin.
Since you are using Cygwin, I suspect that you have tonj convert all the newlines to the windows format for it to work:
It seems that configure has only \r, or so called "carriage returns", as new line character. This is actually the notation used by OSX. Most *nixes use just a single newline character to work (\n). Only windows needs both: a "carriage return" and a newline character: e.g. \r\n.
You can use any professional text editor to change this, for example notepad++.
Looks like a newline issue in whatever file configure is reading. On Windows, lines in text files are terminated with CR/LF (\r\n) - many Unixy tools choke on that.
Visual Studio, among other tools, can recode line termination. Open a file, File\Advanced Save Options, choose Unix line format, then save.
On *nix there's a tool called dos2unix that does the same.

Tesseract-Android-Tools changes and modifications compiled successfully(i think) but no output

Currently I am trying to get tesseract android tools
http://code.google.com/p/tesseract-android-tools/
to work for me on Android. I have been going at this for about a week to no avail.
I am running Win 7 64 bit with cygwin.
I followed the instructions in the readme file and made many changes to the Android.mk files. Basically it was appending a slash to the path, so I had to manually hard code the paths of the individual files, or move to location of the files within the 3 packages to get it to build. However at the end of the build, I did not recieve a "Build Sucessful" notice, but the .so files were generated.
I ported it to eclipse as is and used the following code to get the extracted text.
private static final String TESSBASE_PATH = "/mnt/sdcard/";
Bitmap imageFile = BitmapFactory.decodeFile(image.getAbsolutePath());
TessBaseAPI baseApi = new TessBaseAPI();
if(baseApi.init(TESSBASE_PATH, "eng")){
System.out.println("Tessbase initialized");
baseApi.setDebug(true);
baseApi.setImage(bmp);
String recognizedText = baseApi.getUTF8Text();
System.out.println("---------------------output-------------------");
System.out.println("recognizedText<"+recognizedText+">");
}
else{
System.out.println("Tessbase initialization failure.");
}
At first I was getting an error saying
"Bitmap functions not available; library must be compiled under android-8 NDK"
After taking a look at the tessbaseapi.cpp file I realized that it needed a specific compiler flag to compile the correct function. This flag was -DHAS_JNIGRAPHICS. What I think this means is that the JNI Graphics library must be present.
Yet the program still wouldn't compile because the memcpy() function in the newly compiled method could not be found. I fixed this by changing the actual C++ code to include
Finally the program compiled fully (still wasn't getting a BUILD SUCCESSFUL notice though) and when I ran it, I did not get any output at all. This could be a problem with the eng.traineddata file, or could be a problem in the actual code.
Is there anything I have done wrong? Can someone link me to and eng.traineddata file that they know works and image that works with it?
Thanks in advance!
It's been a few months since you posted this question, however if you're still looking for answers I would seriously recommend that you have a look at the tess-two project on github.
Whilst this won't solve the error that you've posted, its a tactical work around/alternate solution.
It's a fork of tesseract-android-tools and is incredibly easy to use, you'll have it up and running within the hour.
If you're getting poor results, make sure that traineddata file is there, use DDMS file explorer to check its there and not 0 bytes (that happened to me a few times).
Also, make sure you set the whitelist and blacklist characters, this will improve results very well.
Good luck

Categories

Resources