how to call javah from ADT ide - android

Took the basic example from NDK.
Added a function, which doesn't exist yet at native side.
Now I am looking a way to call javah from ADT IDE and expect to be generated the function header to my file, near the others:
extern "C" {
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);
}
;
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height) {
setupGraphics(width, height);
}
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj) {
renderFrame();
}
at least to extern "C" section.
Is there any way to do it? What is the best practice?
generate with a tool to gl2jni.cpp than Cut and Paste to gl_code.cpp, to keep the existing code in gl_code.cpp ? - or do I miss a basic environment setup?
Do I need to write some build configuration? - like always generate those headers to an empty file?
Is there any plugin which can do it from IDE?

Since you are using the Eclipse IDE, running javah can be easily automated to put header files anywhere you want them whenever your Java code is compiled. See my answer on SO here.

Related

C++ on android, how to get app's document directory?

I'm integrating a native c++ library (sqlite3) into android, in order to save the database file I need a path to put it somewhere, on iOS I used this code to get the documents directory:
char *home = getenv("HOME");
However this environment variable not available on Android, is there anyway to get the applications documents path from the c++ or is it necessary to always get it from some higher java call?
Thanks a lot for the help!
Edit
After looking around, I found this small snippet that I already had in my codebase:
SequelModule.initialize(
this.getReactApplicationContext().getJavaScriptContextHolder().get(),
this.getReactApplicationContext().getFilesDir().getAbsolutePath()
);
which is being passed to my cpp-adapter.cpp, how do I convert the second value (the absolute path) JNI/Java string into a C++ std::string?
#include <jni.h>
#include "react-native-sequel.h"
extern "C"
JNIEXPORT void JNICALL
Java_com_reactnativesequel_SequelModule_initialize(JNIEnv* env, jclass clazz, jlong jsiPtr) {
installSequel(*reinterpret_cast<facebook::jsi::Runtime*>(jsiPtr));
}
extern "C"
JNIEXPORT void JNICALL
Java_com_reactnativesequel_SequelModule_destruct(JNIEnv* env, jclass clazz) {
cleanUpSequel();
}

Unresolved symbols NewShortArray and SetShortArrayRegion

I'm trying to use short[] and jshortArray between C/JAVA as follows in Eclipse:
JNIEXPORT void JNICALL Java_com_testingForFun_testFunc
(JNIEnv *env, jclass clazz, jshort num, jshortArray data) {
jshort outCArray[] = {100, 200};
jshortArray outJNIArray = (*env)->NewShortArray(env, 2); // allocate
if (NULL == outJNIArray) return;
(*env)->SetShortArrayRegion(env, outJNIArray, 0 , 2, outCArray); // copy
//return outJNIArray;
}
I've created the header file using javah and included it. However, Eclipse says NewShortArray and SetShortArrayRegion are unresolved and I can't build the apk. However, not using arrays (jshort and short) works fine. I looked in jni.h and it seems that NewShortArray other related functions are defined if __cplusplus is defined, but I'm using C. I also built the apk on the command line using ndk-build and ant and I read outJNIArray[0] or [1] = 0 in the calling function, so it's not working there either. How do I resolve this issue?
Additionally, Eclipse can't resolve ANDROID_LOG_DEBUG in:
__android_log_print(ANDROID_LOG_DEBUG, "FibLib.c", "fibNI(%lld)", n);
even though
#include <android/log.h>
is at the beginning of the file.
I used Eclipse restart and seems to have cleared up these issues. But every time I edit my .c file, the unresolved errors pop up, and I need to restart. It's very annoying. Any fix for this?
The issue of outJNIArray[] not being set is a separate topic, so I will ask another question on the forum in the future if necessary.

NDK unable to deal with #include with relative paths?

I'm writing an Adroid app with some C++ code behind the UI using Eclipse + NDK (r8d). I have some code that I thought was fool proof but the compiler just gives me weird errors like "Invalid arguments" without specifics. Here is what my C++ code looks like:
#include <jni.h>
#include <string>
using namespace std;
#include "../../Evaluator.Engine/Evaluator.Engine.h"
Evaluator evaluator;
extern "C" {
JNIEXPORT jstring JNICALL Java_haskellevaluator_android_MainActivity_evaluateNative(JNIEnv *env, jobject, jstring jInput)
{
...
string sInput(L"Hello world");
string sResult = evaluator.evaluate(sInput);
jstring jResult = env->NewStringUTF(sResult.data());
return jResult;
}
}
Evaluator.Engine.h is nothing fancy, but just a declaration of the class Evaluator.
#include <string>
using namespace std;
class Evaluator
{
public:
string evaluate(string input);
};
However, the compiler complains:
Invalid arguments '
Candidates are:
? evaluate(?)
'
as if string is not defined. But if I put a copy of the header file under the same folder, the error goes away. This is a Windows box. I have tried using \ and escaped \\ as path separators and it didn't work.
Does this sound like a NDK (or whatever the preprocessor it uses) bug? I don't want to move the header file because it'll be shared by other projects. I also hate to keep 2 copies of the same file.
Any ideas? Thanks.
Sorry I don't have windows OS, but I've tried you code on a MacOS, but it doesn't work because of:
string sInput(L"Hello world");
Saying that wchar_t cannot be put on std::string. Is it possible to be the same problem ?

include .h file into java file in android using jni as source folder of .h file?

void ProcedureParams_Initialize(ProcedureParams* pVal);
flag ProcedureParams_IsConstraintValid(const ProcedureParams* val, int* pErrCode);
flag ProcedureParams_XER_Encode(const ProcedureParams* val, ByteStream* pByteStrm, int* pErrCode, flag bCheckConstraints);
flag ProcedureParams_XER_Decode(ProcedureParams* pVal, ByteStream* pByteStrm, int* pErrCode);
flag ProcedureParams_BER_Encode(const ProcedureParams* val, ByteStream* pByteStrm, int* pErrCode, flag bCheckConstraints);
flag ProcedureParams_BER_Decode(ProcedureParams* pVal, ByteStream* pByteStrm, int* pErrCode);
typedef struct {
GeneralEvthParams g_params;
DataParams d_params;
} EvtHandlerParams;
how i can add .h file directly into my .java file. i'm using NDk and .h file inside my jni folder.i want to use the functions of header file . how i can directly use functions in java activity? please help me
You cannot invoke the C/C++ functions directly. The C implementations of Java native functions all have a very specific set of parameters:
JNIEXPORT jint JNICALL Java_com_mycompany_MyClassName_myfunc
(JNIEnv * env, jobject obj, jint code) {
...
}
So you will have to create wrapper functions.
A reasonable approach is to define a class including the Java versions of all your native functions (as either static or instance methods), and invoke them via that class.
To generate C headers from the Java (well, not source but the .class files), you can do:
cd bin/classes
javah com.mycompany.MyClassName com.mycompany.AnotherClassName

Identify Calling Application in Android NDK

I have a native android library (.so) I am bundling with some application. In the native code I want to verify the signer/package name of the calling application.
The reason is, currently anyone can open up the .apk file take my .so file and use it to built their own applications.
Is there a way to securely identify the calling application from Java side? This could be package name, signature or anything else that can identify the Android application in a unique way.
JNI code is coupled with Java package name, and can be called only from the same package and class. To improve security further, you can check some Java private static final field from the JNI code.
In the native code I want to verify the signer/package name of the
calling application.
how about this?
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring JNICALL
Java_com_x_y_TestActivity_stringFromJNI(JNIEnv *env, jobject thiz)
{
jclass jActivity_class = env->GetObjectClass(thiz);
jmethodID jMethod_id_pn = env->GetMethodID(jActivity_class,"getPackageName","()Ljava/lang/String;");
jstring package_name = (jstring) env->CallObjectMethod(thiz,jMethod_id_pn);
return package_name;
}

Categories

Resources