Android Studio JNI: cannot compile JPEG c-library - android

My program needs to read jpeg-images from a file native. For that purpose I downloaded official jpeglib c-source code and that works flawlessly on a Windows version of this program, which is programmed using Embarcadero RAD Studio 8.
But when I try to use the same source code in Android Studio JNI, I see lots of errors almost every c-source file :( Below is a screenshot:
As you can see, there's errors on both
-Macro expansions (ERREXIT, red underlines), which complain "class 'blahblah' doesn't have a field 'blahblah'".
-member methods (red text in code), which complain also "class 'blahblah' doesn't have a field 'blahblah'".
Looks like there are many C-language classes and fields, or probably all, which are not working. But the jpeglib source definitely contains them all, something is just not working in Android Studio! Probably Android Studio C-compiler is somehow limited, but there must be some way to bypass it...
This problem doesn't exist in C++ source files. I have different source folders for java and C++ source files (and there are also separate jni folder, but I don't use it, probably I should), but C source files resides inside the C++ folder. I have added all c, cpp, h and hpp source files inside the parentheses of the CMakeLists.txt's add_library() directive, but that's all. I don't know is it enough...
I'm glad to get any suggestions how to fix this.

It is not enough to add all libjpeg files to your add_library(). The library expects to be configured for the specific toolchain, see e.g. this example.
I prefer an optimized version of the library, called libjpeg-turbo. On GitHub you can find step-by-step instructions how the library can be cross-compiled for Android.

Well, there seems to be happy ending...
I have to admit that Android Studio most likely can compile JPEG c-library:) The problem "class 'blahblah' doesn't have a field 'blahblah'" was because the library needs to be configured for the specific toolchain, like #Alex Cohn said. But the configuration doesn't happen in CMakeLists.txt, instead you need to rewrite the code itself at some extent. For example, you need to change
-INT32 to int32_t
-#define boolean bool
-#define EXTERN extern
-add lots of #include <> and #include ""
-and more...
If you need to do that, start from header files: don't touch C files until you have headers error free. As a side note, I had exactly the same build order in Android Studio than I had in Embarcadero Studio, but that didn't helped to succeed... I don't know yet, will this modified library work, but at least I think I will get rid of compilation errors!

Related

SDL2 compiling for Android with GLEW

This is a compilation problem, specifically with referencing shared libraries with NDK.
I have the SDL2 + GLEW program running fine on my mac (obviously with a different makefile/build system), and I have it running fine on Android as well (so long as I don't use GLEW). But now I need to use GLEW, and can't find a straightforward reference for how/where/what the heck is going on with including libraries in the NDK.
Anyways- in my android-project folder, I have jni/src/Android.mk (which I assume is where I should be looking?)
There's a line with LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image, and I assume that's the magic variable that I shlould add GLEW to? But what even is that? How does that know what GLEW even means? Should it be -lGLEW? (that last question is rhetorical- I've tried all of them and nothing works). I've even tried commenting out that line totally and get the same build error:
jni/src/src/main.cpp:8:21: fatal error: GL/glew.h: No such file or directory
#include <GL/glew.h>
I'm pretty much totally lost... does anyone have any resources I could look into?
Also, as a note, I'd also prefer an explanation regarding why/what is going on, as I'm sure I'll be including other stuff as I go on.
Edit:
As Drop pointed out below, this wasn't a linking problem- the compiler needed to know where to find GL/glew.h. So I added /usr/local/Cellar/glew/1.12.0/include to the LOCAL_C_INCLUDES := line, and that works. But now, there's an error compiling glew.h- GL/glu.h: No such file or directory.
So now,
is there a more general/clean/better way than hardcoding the whole /usr/local/Cellar/glew/1.12.0/include line to let the compiler know where GLEW is? Should glew.h be located somewhere more general?
Why do I only need this when compiling for android? The mac build doesn't need these flags...
I can't find clear documentation anywhere about this, but in compiling the mac build with GLEW, I didn't need to also install GLU and GLUT (like GLEW's website implied...), and further, neither GLU nor GLUT are available as packages via brew.
I've been looking around for documentation about this, but I feel like I don't know what I don't know. Is there some insight you could give to where I'm going wrong regarding how includes and libraries and stuff are expected to be referenced across platforms?
Welp. Turns out there isn't a straightforward way to include GLEW/GLU/GLUT with NDK? (I have a question mark because I'm still not 100% sure...).
However, I found the solution to my problem, and that was- I didn't need GLEW (or GLU, or GLUT, etc...)!
Like I said, I'm building for OSX and android, so I'm using OpenGL 2.1 and OpenGLES2.
I chose to do this because I was told that OpenGLES2 is simply a subset of OpenGL2, so I didn't expect any issues (so long as I didn't use any func's only in OpenGL 2.1).
I needed GLEW because I wanted to use framebuffers (glGenFramebuffers, etc...), which only exist as an extension in OpenGL 2.1. Once I got that working, I assumed I would need the same extension wrangling for OpenGLES2 on Android- turns out I simply don't! It just kinda works out of the box! (Well, once you get NDK working, and linked with OpenGL, and blah blah blah).

can I use an elf file as a library for an apk?

I have code I compiled already, and wonder if I can use the resulting executable, which is in elf format as a library in an APK and how please.
#Gabe Sechan; thanks. I did build a JNI project. I am having some issues importing the code from my other project into JNI. I wonder if you can suggest the best way to import it. I can post my Android.mk file if you like. Basically, it seems that project finds the first file, and an associated header file. That file, in turn uses variables, which are defined in another file. But there is no include statement.
You know? I figured if I can use a JAR file as a library, perhaps I could use an executable also. I need to learn more.
# Chris Straton - Thanks. I did edit my post with a comment to address the toolchain issue. But then, I modified it. Regardless, What I stated was if I use the toolchain that is recommended by my target platform, then I should be able to run it on my phone right?
Further; I re-read your comment about ABI and libc compatibility. The two devices are tegra t132 and Samsung S-N900P. So libc should not be an issue since both devices run Android; right? As far as I know both have an arm chip. Is there anything else I need to look into?
Elf is an executable, not a library. What you want to do is get a .so file and link to it via JNI.
You could possibly run it as a command line program and interact with it via its stdin and stdout, but that would be clunky when you can just use it as an actual library.

How to use/incorporate CPP files to Android project?

We have developed an iPad application where the core logic is written in CPP code, so that we can use the same code files/libraries to other platforms.
Now I want to use those files and develop similar Android application, but unable to create .so files and integrate paths in Android.mk files and all. I am basically an iOS developer, this is first time I am looking into Android NDK.
Can anyone help and guide if there is any straight forward steps to it.
I have already gone through android developers site and few other tutorial sites. But none of those worked for me.
Require easy-clear steps to call cpp method in java, if I do have few cpp files and .a libraries with me already.
You aren't very specific at the step you are stuck at.
Here's a very quick explanation on how to call native code from java (android) :
first create a method to be exported by the native and called by java (this uses JNI, so google JNI , JNIEXPORT)
once you have this method defined in your native code, it's time to create a shared library (.so) file , using the compiler that comes in the NDK (because you are compiling for android ). You will need to compile for the correct architecture of the device (armeabiv7s is the most common now days).
you need to add the library file in your app.apk inside the armeabi folder (more details in NDK tutorials).
inside your java code you will need to load the shared library via the System.loadLibrary(LIBRARY_NAME);
inside your java code you will need to have defined static native methods that are in pair with the methods you exported from your CPP code
Quick tips :
use C functions,not CPP , since CPP will be mangled in the resulting shared library. In other words, you will need to create a C wrapper that will call your cpp code.
look over a hello world tutorial for NDK , and work yourself from there . Here's a link to such tutorial http://trivedihardik.wordpress.com/2011/06/16/hello-world-example-using-ndk-in-android/
You will bump later on into compilation issues with the makefiles, but by then you will probably be able to be more specific with your question.
Easiest way is to use the hello-jni Android studio sample project.
There are a lot of settings and configurations, you get them from the sample that is a working unit, always easiest when starting from something working.
First run (and modify) the hello-jni and learn how the interactivity between the Java and C parts works. About everything works except environmental ANSI C/C++ stuff. You have to get things like language, country etc from Java and transfer it to the C-code. You are in US in English with "inches and gallons" in JNI.
Then to an own project you create with android studio, copy and modify from it bit by bit from hello-jni. When you have our own branded hello-JNI you can add bit by bit your own code. Often using C-dummies for testing the interactivity with the Java part is easier, then change it to the real C/C++ code of yours.
Read the Android/Android studio documentation and learn and understand. Use the Android emulators, much easier and they are good.
The project configuration stuff is by far the hardest to handle at the start. If I would make a new project today, I would start from the Hello-JNI once again.

Eclipse can't read code format of RenderScript .rs file

I have a very good Java knowledge for Android (1 year of development), and now I'm trying to learn the Android RenderScript API (but there isn't much documentations for it) anyway, I'm having some problems with it.
I learned that we need to add the following lines on project.propert:
renderscript.target=19
renderscript.support.mode=true
I created a .rs file in com.mypackage.script called FireworkScript, which has the following:
#pragma version(1)
#pragma rs java_package_name(com.mypackage.script)
#include "rs_graphics.rsh"
int root(){
return 0;
}
void init(){
}
Innitially I had some problems with the RenderScript v8 support library, but I fixed it by manually adding the renderscript-v8.jar to my project (Build Path >> Configure Build Path >> Libraries >> Add External JARs)
As expected, Eclipse generated the ScriptC_FireworkScript.java at gen folder and the fireworkscript.bc at bin/res/bc/raw
But the problem is: Eclipse doesn't "read" the code inside the .rs file, writting on this file using eclipse is the same as writting on any single text editor.
I know the sample above needs a Kernel, but how can I write it, if Eclipse doesn't read its code format? I know the simple typedef struct constructor in C, but I'm not familiarized with kernel declarations and arguments in C99
I can only find errors using project > clean, it seems to "refresh" the compiler, but anyway, I don't have any identation help, text-coloring, anything, only a file with black texts on it, what can I do to fix this? I also tried to open the .rs file with Dev C++ and Notepad++, but I had the same result. Maybe my machine doesn't know the C99 code formating?
Is there anything I can do?
Thanks in advance.
I'm using Eclipse Luna with ADT pluging, SDK build tools currently on 23.0.2 and everything is updated to the latest version.
The C99 specification RenderScript uses for its kernel code is simply C, so you can use any editor capable of editing C/C++ files such as those two you mentioned. This should help you get syntax highlighting at least. You'll just need to configure them to treat .rs files as C code. See for example this page that explains how to do that in Notepad++.
If you really want to keep everything within Eclipse though, you could also try installing the C development environment for Eclipse, but that might be overkill just to get syntax highlighting there. I doubt you would get any actual context/function help or better error reporting with that, since the RS API is still not well integrated into any IDE anyway.

Mac Eclipse not resolving C++ lib functions in NDK

I'm developing a native application using Eclipse for Mac and I can't get std::string or std::map to resolve.
I've already had to add a number of include directories to the path to handle the NDK not being set up that well out of the box; currently I have
.../Development/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.8/include
.../Development/android-ndk-r9/platforms/android-18/arch-arm/usr/include
.../vuforia-sdk-android-2-6-10/build/include
.../android-ndk-r9/sources/cxx-stl/system/include
set as C++ symbol paths, and #include <string> seems to have worked fine. However, all the references to std::string are not resolving, and Eclipse says
Type 'std::string' could not be resolved.
I know this code builds because I successfully built it on a Windows PC; it's an eclipse problem of some description. What can I do to make these symbols resolve?
EDIT 1: I've looked inside <string> and it seems that it mainly contains a bunch of other includes, for example #include <bits/c++config.h>. All of these seem to resolve, but I am going to see if I can find them and determine where std::string actually lives.
EDIT 2: I can find std::basic_string, but not std::string (yet).
EDIT 3: std::basic_string is not apparently visible to my source code either.
Im not sure if this will be an answer for you. My experiences are different, I'm on Windows, and I was only trying to get C (not C++) code working. But ran into exactly the same issue. And my solution could seemly be used to work for C++ as well. As far as I can tell, Eclipse/ADT on Mac is much the same as on Windows. So that shouldn't be a problem here. Who knows, I could be talking out of my a--.
However, I think the problem is solved two fold. Here is how I solved it. I followed the tutorial: http://mhandroid.wordpress.com/2011/01/23/using-eclipse-for-android-cc-development/
Things to note:
1) When developing in Eclipse/ADT for Android. It always assumes that your writing in Java. You need to make the project "Mixed Java & C/C++" (not that I've seen it called this outside the tutorial, lol)
2) Your ndk-build should probably work fine from the command line (even tho it might not compile in Eclipse).
3) In the tutorial, the two things that seemed to get it to recognize C/C++ are "Step 5: Convert to a C/C++ Project" followed by Steps 6-8 (which seem like one big step).
4) In Step 7, under "Build command". You might have to use a the complete path (no spaces) to your ndk-build. (*Windows users enter "ndk-build.cmd" here)
5) In Step 8, also include a full path.. no spaces. However, this is where you would put a path in for "GNC C++" instead. (This is my guess for your solution)
6) If all else fails... It should work in C. Try Step 8 exactly, and use only C syntax. Because, at the top of this older tutorial (http://mindtherobot.com/blog/452/android-beginners-ndk-setup-step-by-step/) it talks about how limited NDK is. It says C++ functionality is limited. Otherwise, this second tutorial is mostly obsolete it seems. Cygwin and command line compilation are not needed anymore, and my Eclipse installation had the C/C++ support out-of-box. However, its all still usable/valid.
PT
(and on a similar note, and for those seeking help with NDK. Also make sure a space-less full path to your NDK folder is entered in at Eclipse > Window > Preferences > Android > NDK > NDK Location)

Categories

Resources