How to get ANativeActivity pointer un Cpp without using android_app* - android

In Android, using JNI in my Java application, I need ANativeActivity to manage resources. My problem is that I have not:
void android_main(struct android_app* state)
because I just call some functions using JNI. Usually people use_
void android_main(struct android_app* app)
{
struct engine engine;
ANativeActivity* activity = app->activity;
std::string mApkWorkspacePath = activity->internalDataPath;
AAssetManager* mApkAssetManager = activity->assetManager;
}
To get that values from the struct. How can I have the ANativeActivity manually?

this thread is a little old but I've recently been trying to work out the same issue, having some older NDK code that I'm freshening up and having found that all the NDK examples aren't much use to me due to their use of these new structures. I thought I'd pass on my findings here, as it's not all that clear from the documentation and for people approaching the problem from this angle.
The NDK now features a series of helper classes (named 'NativeActivity') to make NDK development easier - I suspect we're both doing the same sort of things as these helpers do, in our own older code.
The 'ANativeActivity' C++ structure refers to one structure that's new to this portion of the SDK. It's defined in and refers back to the Java object 'NativeActivity' that's the class your activities derive from using the new (as of 2015 anyway) helper functions and classes.
As such, there's no way to get at this object using 'raw' NDK calls: it doesn't exist for apps that doen't use that part of the NDK.
You can however look at the source code (see 'NativeActivity.java' and 'android_app_NativeActivity.cpp') and replicate it's functionality using raw NDK calls, or you can switch to using the helper application model instead.

Related

Is it enough to wrap exported functions of a C library using JNI for it to work using JNI?

I am interested about the prospects of using any C library using JNI. Particularly with Android, but I assumed this compatibility should be the same as being compatible with JNI.
Without being an original developer of some C library, I've found it confusing to know, what methods I need to register in JNI_OnLoad (https://developer.android.com/training/articles/perf-jni#native-libraries).
To progress, I figured out with the help of https://stackoverflow.com/a/4514781/4959635 to call
nm myclib.a | grep " T "
to find a list of (supposed) "exported functions". However, the nm output may well tell other things as well.
Now my question is,
will/could/should a library work, if I wrap only the exported functions via JNI_OnLoad?
Or do I need to ensure other qualities in the library in order to guarantee that it will work with JNI?
On the other hand, I read some other discussions such as:
https://www.thecodingforums.com/threads/unsatisfiedlinkerror-when-loading-shared-lib.360242/
which suggested that having undefined symbols might mean that the C code is not structured properly for JNI.
Whereas this resource:
https://www.baeldung.com/jni
seems to suggest that wrapping exported functions is in fact what's expected.
No. Functions you call from JNI must always follow a specific signature: (ignoring the return type for now)
fun(JNIEnv *env, jobject obj, ...)
or
fun(JNIEnv *env, jclass cls, ...)
where the remaining arguments are types that the JVM can process.
You will need to create wrapper functions that go between the JVM types and whatever types your functions expect. See the SWIG library for a potential means of auto-generating these wrappers, but know you will still need to write quite a bit of custom code.

How JNI works on the memory level

I have a java file which loads .so files and prints the result coming from .so file. I don't have a source code for my .so file. Can anyone tell how in the memory structure .so results are loaded and from where this Java class is reading the results generated by .so and printing them out??
If u have any code that is already written in native language and reluctant about changing it but you would want to use native calls in your java codes and not to rewrite entirely everything java. JNI comes in handy. it converts all your platform specific implementations to platform independent. Performance- and platform-sensitive API implementations in the standard library allows all Java applications to access this functionality.
the library files .so are converted in such a manner.
JNIEnv contains all types of conversion from a native data types to the java data types. it also supports suitable implementations for native method calls, signals are also handled by the JVM.
Java being platform independent native processss specific to a hardware and operating system platform are all made platform independent by mapping native data types and method calls to java. JNI performs the above using the library files example .so or .a files
For JNI mapping u can refer the below link
http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html
Your .so have a JNI glue class that binds all your Java native methods (public native void x();) with compiled native code.
I'm assuming it uses JNI, otherwise I have no idea how its working. If it uses JNI, then it actually creates Java objects on the Java heap in the .so, using the JNI libraries. Look for functions marked "native", these functions map directly to functions in the so that are called when th Java code whats to run something in the library.
The Droidfish Android chess game is written in Java. But its underlying chess engine Stockfish is written in C++. At first, I thought there was a JNI layer that connects these two but there isn't. The C++ stockfish executable is launched, and Java and C++ communicates via stream.
You can launch the C++ stockfish and play with this engine in the command line, no graphical interfaces.
In your question, your native .so library is printing something to stdout/stderr and you want to read these outputs in Java?

How setup libsvm in Android?

Im trying to setup libsvm in android to detect motion from accelerometer. I have no idea how to setup libsvm in android and how to use it. guys can you give clue for this ?
You do not setup libsvm, simply use the library wrapper for the language you are using to develop an app for android (Java I guess?). Wrapper is included in the official release. And it also includes the sample of usage of this particular library. There is nothing special here - if you know how to develop android app, then using additional library should not be a problem. If you do not know how to develop such an app - then starting from motion recognition is a bad idea. The same applies for ability to use SVM for anything. If you haven't ever used SVM it would be better to start with something simplier, like writing the "non mobile" version of the app and getting familiar with this model. Otherwise, probability of failing is quite big.
Sorry for my previous wrong answer format
Since the libsvm is written in C, you can easily wrap the code via JNI interface and use libsvm in Java.
A wrapper can be found in: https://github.com/yctung/AndroidLibSvm
For example, once you import this project in Android studio, you can call
jniSvmTrain(String options);
to make the svm training with the same interface of original libsvm.
If you look at the code, it is simply a wrapper of original "svm-train.c" in libsvm
#include "./libsvm/svm-train.h"
// helper function to be called in Java for making svm-train
extern "C" void Java_edu_umich_eecs_androidlibsvm_MainActivity_jniSvmTrain(JNIEnv *env, jobject obj, jstring cmdIn){
const char *cmd = env->GetStringUTFChars(cmdIn, 0);
debug("jniSvmTrain cmd = %s", cmd);
std::vector<char*> v;
// add dummy head to meet argv/command format
std::string cmdString = std::string("dummy ")+std::string(cmd);
cmdToArgv(cmdString, v);
// make svm train by libsvm
svmtrain::main(v.size(),&v[0]);
// free vector memory
for(int i=0;i<v.size();i++){
free(v[i]);
}
// free java object memory
env->ReleaseStringUTFChars(cmdIn, cmd);
}
"Setuping" I think you are asking to add the jar file the LIBSVM provide as a library to your android studio project. You can take a look here:
Android Studio: Add jar as library?
In the LIBSVM website you can download a zip file with the JAVA jar file inside and examples of usage.

Passing Camera.MAIN in Unity3D to android java method

i'm working on integrating image recognition app using Moodstocks SDK ,
to start the scanner in moodstocks i must use a surfaceview (Camera) , all works fine when i do it in eclipse , but i want to use unity3D cause i'm making it in a sort of a game ,
so i made my eclipse project as JAR and imported it in unity and i'm trying to call the method in my java class from the unity script and pass the camera.Main to it
so if you can give me any guidelines about that
Thanks,
There are several ways to create a Java plugin but the result in each case is that you end up with a .jar file containing the .class files for your plugin. One approach is to download the JDK, then compile your .java files from the command line with javac. This will create .class files which you can then package into a .jar with the jar command line tool. Another option is to use the Eclipse IDE together with the ADT.
Once you have built your Java plugin (.jar) you should copy it to the Assets->Plugins->Android folder in the Unity project. Unity will package your .class files together with the rest of the Java code and then access the code using the Java Native Interface (JNI). JNI is used both when calling native code from Java and when interacting with Java (or the JavaVM) from native code.
To find your Java code from the native side you need access to the Java VM. Fortunately, that access can be obtained easily by adding a function like this to your C/C++ code:
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* jni_env = 0;
vm->AttachCurrentThread(&jni_env, 0);
}
This is all that is needed to start using Java from C/C++. It is beyond the scope of this document to explain JNI completely. However, using it usually involves finding the class definition, resolving the constructor () method and creating a new object instance, as shown in this example:-
jobject createJavaObject(JNIEnv* jni_env) {
// find class definition
jclass cls_JavaClass = jni_env->FindClass("com/your/java/Class");
// find constructor method
jmethodID mid_JavaClass = jni_env->GetMethodID (cls_JavaClass, "<init>", "()V");
// create object instance
jobject obj_JavaClass = jni_env->NewObject(cls_JavaClass, mid_JavaClass);
// return object with a global reference
return jni_env->NewGlobalRef(obj_JavaClass);
}
This explanation comes from this information page, where a few examples are written as well. You should take a look over here! This may be worth a read as well.
Disclaimer: I work for Moodstocks.
The ScannerSession object in the Moodstocks SDK for Android is designed to be a high-level, easy-to-use wrapper that takes care of many "technical" difficulties by itself, in the context of a classic, Java app. In particular, it initializes the camera for you, previews it on the provided SurfaceView and dispatches camera frames to the Moodstocks SDK.
I've never used Unity myself so I can't dive into the details, but I think that in your context, given the fact that Unity has its own way of initializing and using the camera, you'll have to bypass this ScannerSession object and hit lower-level functions of the Moodstocks SDK. Find how to get the camera frames using Unity, and feed them manually to the Moodstocks SDK Scanner object. You can take inspiration from what is done in the ScannerSession to see how to do that!
Hope this helps! If you're looking for more advice, you can ask us questions on the Moodstocks Help Center

Linker stripping unused classes

I am working on a cross platform project in C++, under IOS and Android, and I am having the following situation
:
I am writing a library used to load scene graphs directly from xml files describing them. The library has a base tree node class, that implements all the functionality to make a class constructable by it's name. Then additional tree nodes are implemented, all deriving from this base node class. This works excellent but there is one problem. The linker 'thinks' that some of my classes are not going to be used and strips them out of the library. I have a nasty workaround right now, having a file that includes all existing nodes headers, and in this file one instance of every node is being created and altered to indicate the compiler/linker that this class is really being used.
Does anybody know a good design pattern that can be used to automatically generate the required instances of all classes?
I have tried to create macros that are placed into the classes cpp file that creates a static instance of the given class, but the linker still detects that those static instances are never going to be referenced.
Or is there a linker flag that can be used to tell the linker not to strip any unused classes out? Like already mentioned: I am working on Android (ndk 6.0) and on IOS (xcode 4.2)
This problem is not going to be a showstopper for my project but it would really be nice to find an acceptable solution here.
It is implementation-defined whether the dynamic initialization of a non-local variable with static storage
duration is done before the first statement of main. If the initialization is deferred to some point in time
after the first statement of main, it shall occur before the first odr-use (3.2) of any function or variable
defined in the same translation unit as the variable to be initialized.
Therefore there's no standard way to guarantee the construction of those objects but to list them all in one specific place.

Categories

Resources